调整大小时夏普图像库旋转图像?
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();
【讨论】:
以上是关于调整大小时夏普图像库旋转图像?的主要内容,如果未能解决你的问题,请参考以下文章
使用 node sharp 包调整图像大小并上传到 s3 时,它会旋转