调整大小时夏普图像库旋转图像?

Posted

技术标签:

【中文标题】调整大小时夏普图像库旋转图像?【英文标题】: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))

原始大图:

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

【问题讨论】:

【参考方案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();

【讨论】:

以上是关于调整大小时夏普图像库旋转图像?的主要内容,如果未能解决你的问题,请参考以下文章

旋转和调整图像大小 + iPhone

使用 node sharp 包调整图像大小并上传到 s3 时,它会旋转

XCode:调整图像大小使用纵横比并向下移动图像下方的元素

在图像移动/调整大小/旋转操作中在图像周围放置一些指示符

调整 uiview 的大小以及 uiimageview 的旋转

Kinetic js拖放,调整大小和旋转图像