锐利图像库在调整大小时旋转图像?

Sharp image library rotates image when resizing?

当为 node.js 使用清晰的图像调整大小库 https://github.com/lovell/sharp 时,图像正在旋转。

我没有说 .rotate() 的代码,那么为什么要旋转它,我怎样才能阻止它旋转?

我正在使用 AWS 提供的无服务器图像大小调整示例: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))

原大图:

调整大小的图片:注意它也被旋转了:

原来问题是这样的:调整图片大小时,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)

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

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

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

docs 中有更多详细信息。

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

Serverless Image Handler 5.0 的更新答案,自 10/2020 起使用 CloudFormation Stack 模板进行部署:

我将 .rotate() 附加到 image-handler.js 的第 50 行,效果非常好:

const image = sharp(originalImage, { failOnError: false }).rotate();
 const data = await sharp(file_local)
    .resize({
      width: px,
     
  })
    .jpeg({
      quality: quality,
      progressive: true,
      chromaSubsampling: "4:4:4",
    })
    .withMetadata()
    .toFile(file_local_thumb);

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

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

我以特定于 AWS 无服务器图像处理程序的相关方式解决了这个问题,没有更改代码。我在编辑列表中传递 "rotate":null

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

之前它仍然对我不起作用

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

如果您使用带 IPX 提供程序的 Nuxt Image 组件登陆此处,我就是这样解决的:在 nuxt.config.js 文件中,添加以下内容:

  buildModules: [
    [
      '@nuxt/image',
      {
        sharp: {
          withMetadata: true,
        },
      },
    ],
  ],

请注意,模块中的选项多于 documented: https://github.com/nuxt/image/blob/61bcb90f0403df804506ccbecebfe13605ae56b4/src/module.ts#L20