利用FreeImage对图像转格式遇到的问题一则

前言

FreeImage 是一个很知名的免费图形库,其支持格式非常多样,常见的如: bmp, gif, ico, jpeg, png, tiff, webp, psd 等文档均可读取。

近日需编写一个小工具用于在Windows下读取大量不同格式的图片转换为jpeg,就使用了FreeImage库,但在实际使用中碰到一个问题,非常诡异,此文做简单记录。

0x01 问题

​ 在读取带透明通道的图片,如png32bit的位图时,若直接存储为FIF_JPEG此类24bit位图时会出现莫名其妙的内存越界错误,具体为访问了已经释放的内存,致进程挂死,但目标文件会被创建,只是无内容。

​ 由于我通过动态库的方式引用,不好调试,查阅文档也没看到FreeImage_Save函数有相关方面的说明。

0x02 解决方案

​ 最终推测并尝试多个方法,发现需将32bit(带透明通道)的位图先通过FreeImage_ConvertTo24Bits方法转换为24bit位图,再操作这个24bit的位图即可保存为FIF_JPEG格式。

如下代码,将多种格式的图片读取进来,再转换为24bit位图后缩放至指定大小再保存为jpeg,但每一步都有失败的可能,需要增加容错处理。

FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeU(filename);
FIBITMAP *fib = FreeImage_LoadU(format, filename);
FIBITMAP *fib24 = FreeImage_ConvertTo24Bits(fib);
FIBITMAP *res = FreeImage_Rescale(fib24, fileRes.width(), fileRes.height());
FreeImage_SaveU(FIF_JPEG, res, m_targetFilePath.toStdWString().c_str())

​ 不负责任的猜测原因有可能是多出来的透明通道在保存过程中被当做普通数据访问并欲写入文件导致的。

0x03 附言

FreeImage库比较老,有一个C++Warpper,但由于文档中都是C Style的风格,于是就没有用了。在使用过程中,发现很多函数都返回一个新的FIBITMAP,感觉内存泄露的危险性还蛮大的。

​ 另外在Windows下读写需要用FreeImage_LoadUFreeImage_SaveUwchar_t的方式读写。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值