如何生成 HEIC 图片

如何生成 HEIC 图片

IT, VCB-Studio

HEIC 作为 HEVC 在图片编码上的应用,有着很不错的应用前景。通过对编码参数的灵活设置,它可以支持更高的色深,提高色彩还原度;也支持 YUV420 色度抽样,可以增加 HEIC 的压缩能力。

对于如何转换 HEIC 图片,目前主要是两类,五种方法。

使用系统级别的编码器

使用 Windows HEVC Video Extensions

这个方案依赖于 Windows 商店中的 HEVC Video Extensions 或者 HEVC Video Extensions from Device Manufacturer。 你需要从制造商获得兑换码,或者支付 1 美元来安装这个扩展,我这里另外提供一下 HEVC Video Extensions from Device Manufacturer 的下载,可以通过 appx 文件部署,该插件已在 Windows 1809/1903/1909/2004 版本上测试过。

https://cloud.ezapi.net/s/JaXjLjejdacJep8

Add-AppxPackage -Path Microsoft.HEVCVideoExtension_1.0.40203.0_x64__8wekyb3d8bbwe.Appx

使用 XnView/XnConvert

在安装好上述扩展后,即可使用 XnView/XnConvert 进行转换。以 XnConvert 为例:

将文件或者文件夹拖拽到输入窗口

 

在输出中选择 HEIC - HEIF,如果需要修改编码的质量,还可以通过下方的 Settings 按钮设置

接下来点击 Convert 即可生成文件。

使用 PowerShell

这里提供了一个 PowerShell脚本:https://github.com/DavidAnson/ConvertTo-Heic/blob/master/ConvertTo-Heic.ps1

你可以在安装完 Windows HEVC Video Extensions 后使用。

优缺点

这种方法在基本只需要通过 GUI (XnView/XnConvert) 即可完成转换,而且转换出来的图片没有色彩问题,兼容性也较好。但它需要 1 美元安装扩展,同时很难灵活的控制编码参数(例如位深度,deblock 等设置)。在 Linux 平台上也不支持转换为 HEIC 。另外在图片的尺寸不能被 2 整除时,还有额外的 artifact。目前使用该 API 的方法都会遇到这样的问题。

test-xnview

使用预览.app

macOS 自带预览.app,你可以通过它的导出功能转换到 HEIC 文件。

优缺点

这种方法在基本只需要通过 GUI 即可完成转换,而且转换出来的图片没有色彩问题,兼容性也较好。但是编码参数也和 Windows 一样不可控制。

 

使用 x265

由于 HEIC 实际上是 HEVC 的帧内编码在图片编码领域的应用,因此这个操作是可以通过 x265 完成的,下述两种方法在核心的编码方面均使用 x265,因此归为一类。

使用 FFmpeg 和 GPAC

安装环境

这里需要两个软件

你可以从这里获取 FFmpeg,Windows 用户还可以使用 Chocolatey 获取

choco install ffmpeg

GPAC 只需要安装 MP4box 部分。

转换代码

最核心的的代码是 x265 编码以及 MP4box 封装,示例如下


ffmpeg -hide_banner -r 1 -i "example.png" -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2,zscale=m=170m:r=pc" -pix_fmt yuv420p -frames 1 -c:v libx265 -preset veryslow -crf 20 -x265-params range=full:colorprim=smpte170m "example.hevc"
mp4box -add-image "example.hevc:primary" -brand heic -new "example.heic"

这里首先是使用 trunc 保证输入给 x265 的图片尺寸满足能够被 2 整除,并且强制使用 smpte170m (bt601) 以保证 Windows 平台正确解码。

另外我们还可以使用一定的 x265 参数增强编码效果


ffmpeg -hide_banner -r 1 -i "example.png" -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2,zscale=m=170m:r=pc" -pix_fmt yuv420p -frames 1 -c:v libx265 -preset veryslow -crf 20 -x265-params range=full:colorprim=smpte170m:aq-strength=1.2 -deblock -2:-2 "example.hevc"

批量处理

对于一些需要批量处理图像的使用情况,可以使用如下方法:

我的文档\WindowsPowerShell 文件夹下新建一个名为: Microsoft.PowerShell_profile.ps1 的空文件,使用记事本打开,粘贴下面的函数保存。

function mdel($tpath, $tformat){
    dir -recurse -path $tpath -include *.$tformat |%{
        $_.Delete();
    }
}

function imgconv($tpath, $quality,$sformat ,$tformat)
{
    If($tformat -eq "heic")
    {
        dir -recurse -path $tpath -include *.$sformat |%{
            $extentmark = 0;
            $imwidth=magick identify -ping -format "%w" $_.FullName
            $imwidth=[int]$imwidth;
            If(($imwidth)%2 -ne 0)
            {
                $imwidth=$imwidth+1;
                $extentmark=1;
            }
            $imheight=magick identify -ping -format "%h" $_.FullName;
            $imheight=[int]$imheight;
            If(($imheight)%2 -ne 0)
            {
                $imheight=$imheight+1;
                $extentmark=1;
            }
            If($extentmark)
            {
                magick $_.FullName -gravity center -strip -extent "($imwidth)x($imheight)" -quality 100% $_.FullName;
            }
        }

        dir -recurse -path $tpath -include *.$sformat |%{
            $crfoffset = $quality * 10;
            $crfval= 30 - $crfoffset;
            ffmpeg -i "$($_.Directory)\$($_.Basename).$sformat"  -crf $crfval -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2,zscale=m=170m:r=pc" -pix_fmt yuv420p -frames 1 -c:v libx265 -preset veryslow -x265-params range=full:colorprim=smpte170m -f hevc "$($_.Directory)\$($_.Basename).hvc" 2>&1 | Out-Null;
            mp4box -add-image "$($_.Directory)\$($_.Basename).hvc:primary" -ab heic -new "$($_.Directory)\$($_.Basename).heic" 2>&1 | Out-Null;
        }
        mdel $tpath hvc
    }
    Else
    {
        dir -recurse -path $tpath -include *.$sformat |%{
            $quality=[int]$quality;
            $magickquality=$quality * 100;
            #$magickquality="$magickquality"+"%";
            magick $_.FullName -quality $magickquality -interlace Plane -sampling-factor 4:2:0 -strip "$($_.Directory)\$($_.Basename).$tformat";
        }
    }
}

然后管理员身份打开 PowerShell 运行

set-executionpolicy remotesigned

则可以在 PowerShell 中批量转换图片


imgconv "图片所在的目标文件夹" 质量参数 原图格式 目标格式
#例子一 jpg转heic
#这里用的函数是最上方的那个 crf基础为30 质量参数设为1时crf为20 crf设置为3时进行无损转换
imgconv "D:\Download\manga\Akira" 3 jpg heic
#例子二 jpg和png之间互相转换
#当目标格式不是heic的时候 转换仅仅使用imagemagick进行
#这是质量参数会映射为百分比
#即1=100%质量 0.75=75%质量
#在目标格式heic的时候 质量参数是对基础crf的改变
#这里则是直接的百分比映射
imgconv "D:\Download\Manga\bababababa" 1 jpg png

该函数依赖于 ImageMagick,也可以使用 Chocolatey 获取

choco install imagemagick

优缺点

这种方法可以最大限度的控制编码参数,并且也是跨平台的。但是它需要使用一些代码,并且在少数的移动设备上会有无法识别的问题。

使用 libheif

安装环境

这里需要一个软件

  • libheif

在 Linux/MacOS 中你可以直接用包管理器安装,而在 Windows 中你需要下载编译好的可执行文件

转换代码

最简单的生成方式如下

heif-enc -q 90 -p x265:colorprim=smpte170m example.jpg -o example.heic

这里仅指定了色彩空间,如果需要使用更高级的算法编码参数则可以如下操作

heif-enc -p x265:crf=20.5 -p x265:colorprim=smpte170m -p x265:rdoq-level=1 -p x265:aq-strength=1.2 -p x265:deblock=-2:-2 example.jpg -o example.heic

批量处理

对于一些需要批量处理图像的使用情况,可以使用如下方法:

我的文档\WindowsPowerShell 文件夹下新建一个名为: Microsoft.PowerShell_profile.ps1 的空文件,使用记事本打开,粘贴下面的函数保存。

然后管理员身份打开 PowerShell 运行

function imgconv($tpath, $quality,$sformat ,$tformat)
{
    If($tformat -eq "heic")
    {
        dir -recurse -path $tpath -include *.$sformat |%{
            $extentmark = 0;
            $imwidth=magick identify -ping -format "%w" $_.FullName
            $imwidth=[int]$imwidth;
            If(($imwidth)%2 -ne 0)
            {
                $imwidth=$imwidth+1;
                $extentmark=1;
                }
            $imheight=magick identify -ping -format "%h" $_.FullName;
            $imheight=[int]$imheight;
            If(($imheight)%2 -ne 0)
            {
                $imheight=$imheight+1;
                $extentmark=1;
            }
            If($extentmark)
            {
                magick $_.FullName -gravity center -strip -extent "($imwidth)x($imheight)" -quality 100% $_.FullName;
            }
        }

        dir -recurse -path $tpath -include *.$sformat |%{
            $crfoffset = $quality * 10;
            $crfval= 30 - $crfoffset;
            Write-Output "Encoding $($_.Directory)\$($_.Basename).heic"
            heif-enc -p x265:crf=$crfval -p x265:colorprim=smpte170m -p x265:rdoq-level=1 -p x265:aq-strength=1.2 -p x265:deblock=-2:-2 "$($_.Directory)\$($_.Basename).$sformat"-o "$($_.Directory)\$($_.Basename).heic";
        }
}
    Else
    {
        dir -recurse -path $tpath -include *.$sformat |%{
            $quality=[int]$quality;
            $magickquality=$quality * 100;
            #$magickquality="$magickquality"+"%";
            magick $_.FullName -quality $magickquality -interlace Plane -sampling-factor 4:2:0 -strip "$($_.Directory)\$($_.Basename).$tformat";
            }
    }
}

然后管理员身份打开 PowerShell 运行

set-executionpolicy remotesigned

则可以在 PowerShell 中批量转换图片

imgconv "图片所在的目标文件夹"  质量参数 原图格式 目标格式
#例子一 jpg转heic
#这里用的函数是最上方的那个 crf基础为30 质量参数设为1时crf为20 crf设置为3时进行无损转换
imgconv "D:\Download\manga\Akira" 3 jpg heic
#例子二 jpg和png之间互相转换
#当目标格式不是heic的时候 转换仅仅使用imagemagick进行
#这是质量参数会映射为百分比
#即1=100%质量 0.75=75%质量
#在目标格式heic的时候 质量参数是对基础crf的改变
#这里则是直接的百分比映射
imgconv "D:\Download\Manga\bababababa" 1 jpg png

该函数依赖于 ImageMagick,也可以使用 Chocolatey 获取

choco install imagemagick

优缺点

这种方法可以最大限度的控制编码参数,并且也是跨平台的,兼容性较好。但是它需要使用一些代码。

简单总结

作为新一代的图片编码技术,HEIC 的优势不言而喻,目前由于桌面平台上可以用来编码的软件并不是很多,因此提供了上述几种思路。目前我认为比较好的方法是 libheif 或者 macOS 下的预览.app。目前上述方法考虑到兼容性默认使用 YUV420p 8bit 编码,但你也可以通过修改代码兼容 10bit编码提高还原度。

你可以通过如下代码查看生成的 HEIC 文件,确保生成的文件可用。

magick identify output.heic

参考文档

https://nokiatech.github.io/heif/technical.html

https://bbs.saraba1st.com/2b/thread-1931974-1-1.html

https://www.itu.int/rec/T-REC-H.273/en

https://github.com/Mr-Z-2697/awkward_win_batches/blob/main/makeheic-z.bat

Amefs, EFS, HEIC, 教程
上一篇文章
蓝牙设备在 Win/Linux 双系统下的配对
下一篇文章
使用Plex搭建在线音乐库

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Fill out this field
Fill out this field
请输入有效的邮箱地址。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

keyboard_arrow_up