Qt支持heic图片显示

原文链接:Qt支持heic图片显示

一、背景

小孩子两岁了,最近在着手给娃做生活照纪念相册,然后就是某宝上各种聊,了解到的相册种类也是各异,价格更是良莠不齐,小几十到小几百都有,一时间还是难以下手。刚过完年那一阵偶然一次看到姐姐家给小朋友做过各式各样的相册,经过咨询发现有一家质量还不错,然后就是直接咨询商家,当时问的时候还有些小贵,主要是比我姐买的时候贵。。。。。。哈哈哈,然后就是耐心的等待啦,期间也是把小孩子一岁的照片准备好。最近这不是马上618啦,价格果然降了,而且比我姐当时定做还便宜,这还犹豫啥,果断下手。

经过跟商家简单沟通,嗯。。。没问题直接下单,然而发送照片时遇到了问题,平时娃娃的照片都是我媳妇进行拍摄的,她使用的是苹果手机,咱一个常年使用android的屌丝然后就发现苹果手机拍出来的照片格式是heic的,这里不懂的同学可点击链接进行深入了解。跟商家协商几次后,他们是只支持接收jpg格式的图片,哎,路走窄了。

想起来之前给朋友做过一个图片格式转换工具,那索性也把heic格式带上吧,说干咱就干,花了几个小时网上搜集了一部分资料,最终解决,先给大伙上效果图,嗯还不错,演示效果是使用debug模式进行,因此慢一些,不过heic格式的照片显示实际上确实比其他常见格式要慢。

image

二、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库安装

  1. 下载vcpkg这个库,直接github进行克隆 ,如果一次不行多试几次应该就可以,或者直接download zip包

    git clone https://github.com/microsoft/vcpkg
    
  2. vcpkg下载完成后,命令行进入该文件夹根目录,执行bootstrap-vcpkg.bat脚本 ,并等待脚本执行完成,最终会下载一个vcpkg.exe可执行文件,之后我们通过这个可执行文件进行libheif库的编译

  3. 编译64位库vcpkg install libheif:x64-windows

  4. 编译32位库vcpkg install libheif:x86-windows

  5. 编译libheif库时,依赖的库会自动进行下载,这个过程比较慢,如果大家发现下载很慢,也可以根据命令行提醒,查看他正在下载的文件然后自己手动下载并放入对应目录,中断当前命令,然后在重新执行即可

  6. 一切顺利的话libheif库应该就会安装完成,最终生成三个动态库文件,分别是heif.dll、libde265.dll和libx265.dll,如下图所示。

image

图片显示

libheif库编译完成后,我们就可以封装Qt的插件,然后无感显示heic图片文件,这里直接给出示例工程Qt支持heic图片显示,需要的自行下载即可,插件的写法都是Qt约定好的接口,比较简单。

示例工程包含插件代码和heif库使用示例,如下图所示,工程中有个点需要注意下,否则不能正确编译,如图所示,主要就是heif库引用时的路径,为了方便笔者编译这里写了全路径,拿到demo后自行修改为正确路径才可以链接成功。

imageimage

demo程序能正确编译后,会生成test.exe可执行程序,跑起来之后,如下图效果,test工程成功显示example.heic图片,代码中有一个ManualLoad宏,启用这个宏之后使用heif库进行加载heic图片并显示,否则使用Qt插件模式显示图片。

image

嗯。。。想了想还是把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
}

三、参考文章

  1. QT+libheif生产的QT插件基于QImageIOPlugin里面包含工程和所需要的库_HeifHandler资源-CSDN文库
  2. C++ + QT (不使用QT插件模式)的heic图片显示。_qt heic-CSDN博客
  3. [vapkg]解决vcpkg下载缓慢的问题_vcpkg下载慢-CSDN博客

值得一看的优秀文章:

  1. 财联社-产品展示
  2. 广联达-产品展示
  3. Qt定制控件列表
  4. 牛逼哄哄的Qt库
  5. TigerTrade-产品展示

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!




很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


posted @ 2024-05-25 19:45  朝十晚八  阅读(86)  评论(2编辑  收藏  举报

返回顶部