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. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章