如何使用 libheif 1.8.0 在 ImageMagick 7 中将奇数尺寸的图像转换为 HEIC 图像?

如何使用 libheif 1.8.0 在 ImageMagick 7 中将奇数尺寸的图像转换为 HEIC 图像?

简洁版本:HEIC 图像需要具有偶数尺寸。在 Homebrew 安装的 ImageMagick 的早期版本中,libheif 1.7.0 使用了一种临时方法将图像尺寸向下舍入为偶数值,以允许转换具有奇数尺寸的图像。

现在,libheif 1.8.0 已经放弃了这种解决办法,并在这种情况下生成图像,尽管它们是有效的 HEIC 文件,但 macOS 似乎无法打开。

当 Apple 解决这一问题时,我们可以做些什么来干净地转换这些图像,以便 macOS 能够打开它们呢?


较长版本:自 2020 年 7 月左右以来,我一直在断断续续地使用 ImageMagick 将大量高分辨率 JPEG 图像转换为 HEIC 格式,以节省文件空间和数据传输时间,同时保持质量。我使用的是 macOS Catalina 10.5.6 (19G2021),并且已通过 Homebrew 安装和更新 ImageMagick。

上个月,在转换一个装满图片的小目录时发生了一件奇怪的事情:看似任意的图片都可以转换为 HEIC,但我无法在“预览”应用程序或 ma​​cOS 中的 Pixelmator 中打开它们。也没有生成预览图标。更奇怪的是,如果我拍摄该 HEIC 图像然后将其转换回 JPEG,转换就会成功。因此 HEIC 在某种程度上是有效的,但 macOS 的原生 API 无法处理。

根据对 ImageMagick repo 问题报告的此评论事实证明利布海夫— ImageMagick 中处理 HEIC 内容的库 — 最近升级到 1.8.0,新版本处理奇数尺寸图像的转换方式与 libheif 1.7.0 及更早版本不同。对于奇数尺寸的图像,它会创建使用clap(清洁光圈)裁剪变换而 macOS 显然不知道该如何处理。检查我一堆无法打开的图片,它们都至少有一个维度(宽度或高度)是奇数值。

因此,虽然这显然是 macOS 的问题以及它如何本机处理 HEIC 文件,但我现在该怎么做才能恢复批量转换可以在 macOS 中查看的图像?降级到 libheif 1.7.0 似乎很混乱,而且有点倒退。

如果你想亲自测试一下,可以尝试使用以下命令这个测试图像在 Wikimedia 上,其宽度为 3111,高度为 3333;只需将图像重命名test.jpeg为:

convert test.jpg test.heic

或者尝试使用 libheif 实用程序执行相同操作,heif-enc如下所示:

heif-enc test.jpg -o test.heic

在这两种情况下,macOS“预览”应用程序和其他应用程序都无法打开生成的test.heic文件。但显然可以使用 ImageMagick 从命令行将其转换回 JPEG,如下所示:

convert test.heic test.jpg

答案1

让 ImageMagick 在转换过程中将奇数尺寸“四舍五入”为下一个偶数值。

不能依赖 Apple 来更新/修补 macOS 的 API 来处理这些clap图像,所以我现在的解决方案是使用 ImageMagick 本身将奇数尺寸“四舍五入”到下一个偶数像素尺寸,然后将该图像转换为 HEIC。

解决方案来自这个 StackOverflow 答案使用 ImageMagick 的-extent选项和嵌套调用来检查图像大小,如下-format所示:

convert source.jpg -background white -extent  $(convert source.jpg -format '%[fx:2*int((w+1)/2)]x%[fx:2*int((h+1)/2)]!' info:) destination.heic

嵌套调用convert将根据以下内容输出类似以下内容的内容这个测试图像在 Wikimedia 上,其宽度为 3111,高度为 3333:

3112x3334!

是的,它为宽度和高度添加了一个像素,但对于许多用途来说,这可以忽略不计。这是一种有效的解决方法,尤其是对于高分辨率图像。

下面是我现在用来处理这些批量转换的完整 Bash 脚本:

find -E 'Desktop/Pics' -type f -iregex '.*\.(JPG|JPEG|PNG|TIF|TIFF)$' |\
  while read FULL_IMAGE_PATH
  do
    PATH_SANS_EXTENSION="${FULL_IMAGE_PATH%.*}"
    convert "${FULL_IMAGE_PATH}" -background white -extent  $(convert "${FULL_IMAGE_PATH}" -format '%[fx:2*int((w+1)/2)]x%[fx:2*int((h+1)/2)]!' info:) "${PATH_SANS_EXTENSION}".heic
    exiftool -overwrite_original_in_place -tagsFromFile "${FULL_IMAGE_PATH}" "${PATH_SANS_EXTENSION}".heic
  done

libheif 1.9.0 现在有一个新的内置选项,可以将奇数尺寸裁剪一个像素,以使图像尺寸为偶数。

根据libheif 问题线索上的这条评论,libheif 1.9.0 版本现在有一个-E/--even-size选项,可以解决这个问题。

将我本地的 Homebrew 安装的 libheif 更新到版本后,我就可以测试这一点了。当我运行这个不带选项的基本命令时-E

heif-enc source.jpeg -o destination.heic

我看到这个有用的警告:

警告:macOS 上的许多程序无法显示宽度或高度为奇数的 HEIF 图像(已测试至 Catalina 10.15.6)。在修复 macOS 问题或我们找到解决方法之前,建议使用选项 -E 将图像大小设为偶数。

生成的图像与之前一样,有效但无法在 macOS 中打开。

-E但是如果我使用如下选项运行相同的命令:

heif-enc -E source.jpeg -o destination.heic

destination.heic在 macOS 中有效且可打开!

知道我可以调整我自己的 Bash 脚本 — 使用 ImageMagick —heif-inc直接使用如下:

find -E 'Desktop/Pics' -type f -iregex '.*\.(JPG|JPEG|PNG|TIF|TIFF)$' |\
  while read FULL_IMAGE_PATH
  do
    PATH_SANS_EXTENSION="${FULL_IMAGE_PATH%.*}"
    heif-enc -E "${FULL_IMAGE_PATH}" -o "${PATH_SANS_EXTENSION}".heic
    exiftool -overwrite_original_in_place -tagsFromFile "${FULL_IMAGE_PATH}" "${PATH_SANS_EXTENSION}".heic
  done

请注意,该-E选项会将图像裁剪一个像素以使尺寸均匀,而使用该-extent/-format组合的 ImageMagick 命令会添加一个额外像素以使尺寸均匀。对某些人来说可能意义不大,但在选择使用哪种方法时需要记住这一点。

相关内容