当前位置: 首页 > 工具软件 > sharp > 使用案例 >

sharp node图片处理

笪成周
2023-12-01

市场目前公开可处理图片的有七牛云,阿里云等大厂进行图像处理,应某S3Store 业务需求,自行解决图片处理;这里结合node 的sharp库,很好用
npm 地址:sharp - npm
教程API地址:sharp - High performance Node.js image processing

首先进行图片正则规则匹配
 

for (const rule of rules) {
    const m = pathname.match(rule.pattern);
    if (m && rule.process) {
      const fn = async function () {
        const o = await rule.process.bind(rule)(pathname, m);
        if (o.data && o.info && Buffer.isBuffer(o.data)) {
          return {
            data: o.data.toString('base64'),
            info: o.info,
            isBase64Encoded: true,
          };
        }
        return {
          data: JSON.stringify(o),
          info: { format: 'application/json' },
        };
      };
      fn.rule = rule;
      return fn;
    }
  }
里面划分了两个处理文件    基础处理 (模式,宽,高,质量)和高级处理

const sharp = require('sharp');
const createError = require('http-errors');
 
const JPG = 'jpg';
const JPEG = sharp.format.jpeg.id;
 
class ImageView {
  constructor(image) {

    this._image = image;
    this._m = 0;
    this._w = 0;
    this._h = 0;
    this._q = 75;
  }
 
 
  m(v) {
    this._m = v;
    return this;
  }
 
 
  w(v) {
    const width = parseInt(v, 10);
    this._w = width;
    return this;
  }
 
 
  h(v) {
    const height = parseInt(v, 10);
    this._h = height;
    return this;
  }
 
 
  q(v) {
    if (Number.isNaN(v)) throw createError(400, 'Invalid input');
    this._q = v;
    return this;
  }
 
  async process() {
    const image = this._image;
    const metadata = await image.metadata();
 
    if (this._w || this._h) {
      const opts = {};
      if (this._m === 0) {
        opts.fit = sharp.fit.inside;
      } else if (this._m === 1) {
        opts.fit = sharp.fit.cover;
      } else if (this._m === 2) {
        opts.fit = sharp.fit.inside;
      }
 
      image.resize(this._w, this._h, opts);
    }
 
    if (this._q && (JPEG === metadata.format || JPG === metadata.format)) {
      image.jpeg({ quality: this._q });
    }
 
    return image;
  }
}
 
exports.ImageView2= ImageView;

高级处理js文件

const sharp = require('sharp');
const createError = require('http-errors');
 
const JPG = 'jpg';
const JPEG = sharp.format.jpeg.id;
class ImageMogr {
  constructor(image) {
    if (!image) {
      throw createError(500, 'Empty image');
    }
    if (!(image instanceof sharp)) {
      throw createError(500, 'Image must be a sharp object');
    }
    this._image = image;
    this._b = false;
    this._colorspace = false;
    this._q = 75;
    this._thumbnail = async () => {};
    this._crop = async () => {};
  }
  
  q(v) {
    if (Number.isNaN(v)) throw createError(400, 'Invalid input');
    this._q = v;
    return this;
  }
 
  b(v) {
    if (v) {
      this._b = v;
    }
    return this;
  }
  colorspace(v) {
    if (v) {
      this._colorspace = v;
    }
    return this;
  }
  thumbnail(v) {
    const rules = ['业务方正则集合,用于匹配'];
    // eslint-disable-next-line no-restricted-syntax
    for (const r of rules) {
      const m = v.match(r.pattern);
      if (m) {
        this._thumbnail = () => r.proc(m);
        return this;
      }
    }
    throw createError(400, 'Invalid thumbnail query');
  }
  crop(widthNumber, heightNumber, gravity) {
    const w = parseInt(widthNumber, 10);
    if (Number.isNaN(w) || w <= 0) {
      throw createError(400, 'Invalid width');
    }
    const h = parseInt(heightNumber, 10);
    if (Number.isNaN(h) || h <= 0) {
      throw createError(400, 'Invalid height');
    }
    if (gravity === 'center') {
      this._crop = async () => {
        const buffer = await this._image.toBuffer();
        const metadata = await sharp(buffer).metadata();
        if (metadata.width && metadata.height) {
          const x = (metadata.width - w) >> 1;
          const y = (metadata.height - h) >> 1;
          const region = {
            left: x,
            top: y,
            width: w,
            height: h,
          };
          this._image.extract(region);
        } else {
          console.warn('Cannot fetch width/height in metadata');
        }
      };
    } else {
      throw createError(400, 'Invalid crop gravity');
    }
    return this;
  }
  async process() {
    const image = this._image;
    const metadata = await image.metadata();
    if (this._q && (JPEG === metadata.format || JPG === metadata.format)) {
      image.jpeg({ quality: this._q });
    }
    if (this._b) {
      image.blur(50);
    }
    if (this._colorspace) {
      image.pipelineColourspace('grey16').toColourspace('srgb');
    }
    if (this._thumbnail) {
      await this._thumbnail();
    }
    if (this._crop) {
      await this._crop();
    }
    return image;
  }
}
exports.ImageMogr = ImageMogr;

图片信息处理

const sharp = require('sharp');
const createError = require('http-errors');
 
class ImageInfo {
  constructor(image) {
    if (!image) {
      throw createError(500, 'Empty image');
    }
    if (!(image instanceof sharp)) {
      throw createError(500, 'Image must be a sharp object');
    }
    this._image = image;
  }
 
  async process() {
    const image = this._image;
    const metadata = await image.metadata();
 
    return {
      size: metadata.size,
      format: metadata.format,
      width: metadata.width,
      height: metadata.height,
      colorModel: metadata.space,
     
    };
  }
}

 类似资料: