【问题标题】:Sharp image library rotates image when resizing?调整大小时夏普图像库旋转图像?
【发布时间】:2018-07-20 20:09:24
【问题描述】:

当使用 node.js 的锐利图像调整库https://github.com/lovell/sharp 时,图像正在旋转。

我没有显示 .rotate() 的代码,那么为什么要旋转它,如何阻止它旋转?

我正在使用 AWS 提供的 serverless-image-resizing 示例:https://github.com/awslabs/serverless-image-resizing,如果缩略图不存在,它使用 lambda 动态调整图像大小

S3.getObject({Bucket: BUCKET, Key: originalKey}).promise()
.then(data => Sharp(data.Body)
      .resize(width, height)
      .toFormat('png')
      .toBuffer()
    )
.then(buffer => S3.putObject({
        Body: buffer,
        Bucket: BUCKET,
        ContentType: 'image/png',
        Key: key,
      }).promise()
    )
.then(() => callback(null, {
        statusCode: '301',
        headers: {'location': `${URL}/${key}`},
        body: '',
      })
    )
.catch(err => callback(err))

原始大图:

调整大小的图像:注意它也已旋转:

【问题讨论】:

    标签: node.js amazon-s3 aws-lambda image-resizing sharp


    【解决方案1】:

    问题实际上是这样的:当你调整图像大小时,exif 数据丢失了。 exif 数据包括图像的正确方向,即向上的方向。

    幸运的是,sharp 确实有一个功能可以保留 exif 数据,.withMetadata()。所以需要将上面的代码改为:

    S3.getObject({Bucket: BUCKET, Key: originalKey}).promise()
    .then(data => Sharp(data.Body)
          .resize(width, height)
          .withMetadata() // add this line here
          .toBuffer()
        )
    

    (请注意,您还需要删除 .toFormat('png') 调用,因为 png 对 exif 的支持与 jpeg 不同)

    现在它可以正常工作了,调整大小的图像是正确的。

    【讨论】:

    • 我有一个不相关的问题,但我找不到任何信息。我想旋转特定角度的图像(不是 90 的倍数)。我知道 libvips 确实提供了这一点,这可能是没有的原因。有什么建议可以做到这一点(即使是纯 js)?
    • 也可以使用rotate(): '如果没有提供角度,则根据EXIF数据确定。支持镜像,并可能推断使用翻转操作。'
    • 只有我一个人认为这种细节应该是默认的......
    【解决方案2】:

    替代解决方案是在resize 之前实际调用.rotate()。这将根据 EXIF 数据自动定位图像。

    .then(data => Sharp(data.Body)
          .rotate()
          .resize(width, height)
          .toBuffer()
        )
    

    更多详情请关注docs

    这样您就不需要保留原始元数据,从而使整体图像尺寸更小。

    【讨论】:

    • 这很好用,谢谢!!我之前在文档中没有看到这一点,所以我在使用 Sharp 调整大小之前使用另一个库进行旋转。
    • 太棒了!这完美!我认为这个rotate可以在内部被sharp调用来修复旋转,但是没关系。
    • 这很完美!感谢这个提示,因为它允许继续剥离元数据
    • 使用rotate 允许将toFormat("png") 保持在原位。
    • 出于某种原因,如果我使用withMetadata() 方法并尝试仅调整宽度,它会将高度而不是宽度调整为指定值。但这种方法效果很好。
    【解决方案3】:
     const data = await sharp(file_local)
        .resize({
          width: px,
         
      })
        .jpeg({
          quality: quality,
          progressive: true,
          chromaSubsampling: "4:4:4",
        })
        .withMetadata()
        .toFile(file_local_thumb);
    

    使用 (.withMetadata()),防止图像旋转。

    另外你可以只传递宽度参数,你不需要高度。

    【讨论】:

      【解决方案4】:

      我以特定于 AWS 无服务器图像处理程序的相关方式修复了此问题,而无需更改代码。我在编辑列表中传递了"rotate":null

      在阅读最新的 (5.2.0) 代码时,他们似乎试图解决这个问题,但在我添加 "rotate":null 之前它仍然不适合我

      这是 Github 上的一个相关问题:https://github.com/awslabs/serverless-image-handler/issues/236

      【讨论】:

        【解决方案5】:

        无服务器图像处理程序 5.0 的更新答案,自 2020 年 10 月起使用 CloudFormation 堆栈模板进行部署:

        我将.rotate() 附加到image-handler.js 的第50 行,它就像一个魅力:

        const image = sharp(originalImage, { failOnError: false }).rotate();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-07-11
          • 2017-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-27
          • 2021-10-07
          相关资源
          最近更新 更多