Qt支持heic图片显示
原文链接:Qt支持heic图片显示
一、背景
小孩子两岁了,最近在着手给娃做生活照纪念相册,然后就是某宝上各种聊,了解到的相册种类也是各异,价格更是良莠不齐,小几十到小几百都有,一时间还是难以下手。刚过完年那一阵偶然一次看到姐姐家给小朋友做过各式各样的相册,经过咨询发现有一家质量还不错,然后就是直接咨询商家,当时问的时候还有些小贵,主要是比我姐买的时候贵。。。。。。哈哈哈,然后就是耐心的等待啦,期间也是把小孩子一岁的照片准备好。最近这不是马上618啦,价格果然降了,而且比我姐当时定做还便宜,这还犹豫啥,果断下手。
经过跟商家简单沟通,嗯。。。没问题直接下单,然而发送照片时遇到了问题,平时娃娃的照片都是我媳妇进行拍摄的,她使用的是苹果手机,咱一个常年使用android的屌丝然后就发现苹果手机拍出来的照片格式是heic的,这里不懂的同学可点击链接进行深入了解。跟商家协商几次后,他们是只支持接收jpg格式的图片,哎,路走窄了。
想起来之前给朋友做过一个图片格式转换工具,那索性也把heic格式带上吧,说干咱就干,花了几个小时网上搜集了一部分资料,最终解决,先给大伙上效果图,嗯还不错,演示效果是使用debug模式进行,因此慢一些,不过heic格式的照片显示实际上确实比其他常见格式要慢。
二、Heic图片显示
Qt程序要显示heic的图片有两种方式,一种就是插件模式,这种方式最方便,也是使用起来最巴适的,对使用者来说是无感的;另一种方式就是自行加载heic的图片,转为image数据之后再转为pixmap进行显示。
不管是那种方式进行显示heic照片,首先要做的都是安装libheif这个库,嗯。。。怎么搞!当然是百度啦,老前辈都给咱铺好路了,咱们只需要照着做就行。这里主要参考了QT+libheif生产的QT插件基于QImageIOPlugin里面包含工程和所需要的库_HeifHandler资源-CSDN文库和C++ + QT (不使用QT插件模式)的heic图片显示。_qt heic-CSDN博客两篇文章,内容大差不差,如果你访问github速度不是很很稳定,下载资源的过程可能出现卡顿,或者下载不下来的情况,那么可以参考[vapkg]解决vcpkg下载缓慢的问题_vcpkg下载慢-CSDN博客这篇文章,主要就是把命令行需要下载的文件,咱们手动给他下载下来然后放到指定目录。通过上述三篇文章基本上就可以安装好libheif这个库,这里我就不细说每一步的演示截图,只列出关键步骤和注意事项。
heif库安装
-
下载vcpkg这个库,直接github进行克隆 ,如果一次不行多试几次应该就可以,或者直接download zip包
git clone https://github.com/microsoft/vcpkg
-
vcpkg下载完成后,命令行进入该文件夹根目录,执行bootstrap-vcpkg.bat脚本 ,并等待脚本执行完成,最终会下载一个vcpkg.exe可执行文件,之后我们通过这个可执行文件进行libheif库的编译
-
编译64位库vcpkg install libheif:x64-windows
-
编译32位库vcpkg install libheif:x86-windows
-
编译libheif库时,依赖的库会自动进行下载,这个过程比较慢,如果大家发现下载很慢,也可以根据命令行提醒,查看他正在下载的文件然后自己手动下载并放入对应目录,中断当前命令,然后在重新执行即可
-
一切顺利的话libheif库应该就会安装完成,最终生成三个动态库文件,分别是heif.dll、libde265.dll和libx265.dll,如下图所示。
图片显示
libheif库编译完成后,我们就可以封装Qt的插件,然后无感显示heic图片文件,这里直接给出示例工程Qt支持heic图片显示,需要的自行下载即可,插件的写法都是Qt约定好的接口,比较简单。
示例工程包含插件代码和heif库使用示例,如下图所示,工程中有个点需要注意下,否则不能正确编译,如图所示,主要就是heif库引用时的路径,为了方便笔者编译这里写了全路径,拿到demo后自行修改为正确路径才可以链接成功。
demo程序能正确编译后,会生成test.exe可执行程序,跑起来之后,如下图效果,test工程成功显示example.heic图片,代码中有一个ManualLoad宏,启用这个宏之后使用heif库进行加载heic图片并显示,否则使用Qt插件模式显示图片。
嗯。。。想了想还是把Test工程的代码贴上来吧,大家一看应该就能懂,不懂的话会用就行。
//手动加载
#define ManualLoad
Test::Test(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
std::string filename = qApp->applicationDirPath().toStdString() + "/example.heic";
#ifdef ManualLoad
heif_context* heif_ctx_ = heif_context_alloc();
if (!heif_ctx_) {
qDebug() << "!heif_ctx_";
}
heif_error error = heif_context_read_from_file(heif_ctx_, filename.c_str(), nullptr);
if (error.code != heif_error_Ok) {
qDebug() << "heif_error_Ok";
}
heif_image_handle* heif_handle_ = nullptr;
error = heif_context_get_primary_image_handle(heif_ctx_, &heif_handle_);
if (error.code != heif_error_Ok) {
qDebug() << "heif_error_Ok";
}
int width_ = heif_image_handle_get_width(heif_handle_);
int height_ = heif_image_handle_get_height(heif_handle_);
heif_image* heif_img_ = nullptr;
error = heif_decode_image(heif_handle_, &heif_img_, heif_colorspace_RGB, heif_chroma_interleaved_RGB, nullptr);
if (error.code != heif_error_Ok) {
qDebug() << "heif_error_Ok";
}
int stride;
const uint8_t* data = heif_image_get_plane(heif_img_, heif_channel_interleaved, &stride);
//下面为使用QLabel进行展示的代码,其他图形框架根据框架要求 自行展示
QImage img(data, width_, height_, QImage::Format_RGB888);
ui.label->setPixmap(QPixmap::fromImage(img));
#else
ui.label->setPixmap(QPixmap(filename.c_str()));
#endif // ManualLoad
}
三、参考文章
- QT+libheif生产的QT插件基于QImageIOPlugin里面包含工程和所需要的库_HeifHandler资源-CSDN文库
- C++ + QT (不使用QT插件模式)的heic图片显示。_qt heic-CSDN博客
- [vapkg]解决vcpkg下载缓慢的问题_vcpkg下载慢-CSDN博客
值得一看的优秀文章:
很重要--转载声明
-
本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
-
如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。