简体   繁体   English

如何将缓冲区传递给 node.js 中的 imagemin 模块?

[英]how to pass a buffer to imagemin module in node.js?

In older version of imagemin I was able to pass the module a buffer like so:在旧版本的 imagemin 中,我能够向模块传递一个缓冲区,如下所示:

new ImageMinify()
    .src(StreamOrBuffer)
    .use(ImageMinify.jpegtran({progressive: true}))

In the current version of imagemin there is no src function and calling the module will result in a promise.在当前版本的 imagemin 中没有src函数,调用该模块将产生一个承诺。

I could not find how to achieve the same result in newer version of imagemin我找不到如何在较新版本的 imagemin 中实现相同的结果

Could it be done or that the support was removed?是否可以完成或移除支持?

I got an answer from the github repo.我从 github 仓库得到了答案。 I'm posting the answer here in case someone else will encounter the same problem:我在这里发布答案,以防其他人遇到同样的问题:

You can supply a buffer using imagemin.buffer .您可以使用imagemin.buffer提供缓冲区。 Streams has never been supported. Streams 从未被支持。

Here is a function that:这是一个函数:
- resize an image within given sizes using sharp - 使用锐利在给定尺寸内调整图像大小
- use imagemin with buffer to compress the image (it convert the stream to a buffer to do so) - 使用带缓冲区的 imagemin 来压缩图像(它将流转换为缓冲区来执行此操作)
- save the buffer - 保存缓冲区

I did not find a good way to make imagemin compatible with stream with style, so it use a temp writable stream to store the buffer.我没有找到使 imagemin 与带有样式的流兼容的好方法,因此它使用临时可写流来存储缓冲区。


/**
 * It:
 * 1. Resize the image directly from a GCP read stream to a 500x500 keeping the aspect ratio
 * 2. Create a temp Writable stream to transform it to buffer
 * 3. Compress the image using 'imagemin'
 * 4. Save it to GCP back
 * 5. Delete original image
 *
 * @param filePath
 * @param width
 * @param height
 */
const resize = async (
    bucket: Bucket,
    filePath: string,
    width: number,
    height: number
): Promise<[File, string]> => {
    const ext = path.extname(filePath)
    const fileName = path.basename(filePath, ext)

    const [imageMetadata] = await bucket.file(filePath).getMetadata()

    const metadata = {
        contentType: imageMetadata.contentType,
        predefinedAcl: 'publicRead',
    }
    const newFileName = `${fileName}_${width}x${height}${ext}`
    const thumbFilePath = path.join(path.dirname(filePath), newFileName)
    const outputFile = bucket.file(thumbFilePath)

    const bufferData: any[] = []
    const tempWritableStream = new stream.Writable()
    tempWritableStream._write = function(chunk, encoding, done) {
        bufferData.push(chunk)
        done()
    }

    const pipeline = sharp()

    bucket
        .file(filePath)
        .createReadStream()
        .pipe(pipeline)

    pipeline
        .resize(width, height, { fit: 'inside' })
        .jpeg({ progressive: true, force: false })
        .png({ progressive: true, force: false })
        .pipe(tempWritableStream)

    return await new Promise((resolve, reject) =>
        tempWritableStream
            .on('finish', async () => {
                const transformedBuffer = await minimizeImageFromBufferArray(
                    bufferData
                )
                await saveImage(transformedBuffer, outputFile, metadata)
                await bucket.file(filePath).delete()
                resolve([outputFile, newFileName])
            })
            .on('error', reject)
    )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM