IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【AVD】简述 C++ 解码 HEIF HEIC 图片 -> 正文阅读

[C++知识库]【AVD】简述 C++ 解码 HEIF HEIC 图片

随着软硬件技术的不断升级,相机像素越来越高、人们对照片细节的要求越来越多,高压缩率、低损失率的编码格式,heic 越来越多地出现在人们的生活中,现在 iOS 相机已经默认保存 heic 格式的图片了。而通常情况下,FFmpeg 是不支持对 heif 解析的。

无法解析 heic 格式的 FFmpeg

当第一次遇到 HEIC 格式的图片时,遇到了 FFmpeg 的报错,av_format_open_input() 这个接口的调用就失败了,也就是说,FFmpeg 对 HEIC 这种封装格式没法解析。

简单了解了一下 HEIC 相关的知识点,它是使用 hevc,也就是 h265 编码格式压缩的。因此,解码其实并不是问题的所在,heic 的封装格式才是。

自带示例 demo 的 libheif

通过查资料发现,一个比较常见的 C++ 解析解码 heic 格式图片的开源库是 libheif,而这个库对 h265 的解码过程又依赖于另一个开源 C++ 库 libde265

同时从 github 上下载了这两个开源库。根据 github 上两个库 readme.md 的内容,依次编译通过 libde265 和 libheif 之后,就可以参考 libheif/examples/heif_convert.cc 来完成一个简单的对 HEIC 格式图片的解析、解码的过程。主要调用的函数如下:

#include <libheif/heif.h>
bool decodeheif(string filename) {
  	// 类似于 ffmpeg AVFormatContext,heif 也需要一个上下文环境
  	heif_context* heif_ctx_ = heif_context_alloc();
  	if (!heif_ctx_) return false;
	// 读取文件
	heif_error error = heif_context_read_from_file(heif_ctx_, filename.c_str(), nullptr);
  	if (error.code != heif_error_Ok) return false;
  	// 获取图片句柄(handle),这里,primary 可以理解为主图片。因为 heif 格式是支持将图片的原始图片(主图片)和不同等级的缩略图一起放在同一个文件里的。因此,如非需要,我们主要获取其主图片即可。再注意,这里传入的是指针的指针,即 heif_image_handle**
  	heif_image_handle *heif_handle_ = nullptr;
  	error = heif_context_get_primary_image_handle(heif_ctx_, &heif_handle_);
  	if (error.code != heif_error_Ok) return false;
  	// 获取图片宽高,注意,由于之前我们是获取的是主图片的句柄,因此这里获取的是当前句柄下图片的宽高
  	width_ = heif_image_handle_get_width(heif_handle_);
  	height_ = heif_image_handle_get_height(heif_handle_);
  	// 解码,注意,这里需要再申请一个 heif_image 的指针变量,并将其地址传入该函数,即作为传出参数使用。
  	// 此外,这里的 heif_colorspace_RGB 也可以用 heif_colorspace_YCbCr,
  	// 同样地,后面的 heif_chroma_interleaved_RGBA 也可以用 heif_chroma_420 代替,
  	// 来获取 YUV 420 的图像数据,可能解码效率上会快很多
  	heif_image* heif_img_ = nullptr;
	error = heif_decode_image(heif_handle_, &heif_img_, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, nullptr);
  	if (error.code != heif_error_Ok) return false;
  	int stride;
  	// 解码完成之后,还需要调用下面的方法来获取解码数据的只读地址。拿到地址后如何使用,则看自己的了。
  	// 我通常是直接 memcpy 到一个内存去使用,当然,也可以直接直接 glTexture2D 到 GPU 显存中去
  	const uint8_t *data = heif_image_get_plane_readonly(heif_img_, heif_channel_interleaved, &stride);
  	if (data == nullptr) return false;
}

对 libheif 相关环境变量内存的释放也很简单:

  if (heif_ctx_) {
    heif_context_free(heif_ctx_);
    heif_ctx_ = nullptr;
  }
  if (heif_handle_) {
    heif_image_handle_release(heif_handle_);
    heif_handle_ = nullptr;
  }
  if (heif_img_) {
    heif_image_release(heif_img_);
    heif_img_ = nullptr;
  }
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 21:57:27  更:2021-12-26 21:57:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:31:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码