本文从三个方面讲解如何使用opencv的cv::imwrite()函数生成透明/不透明的PNG图像:
1. PNG图像简单介绍
2. cv::imwrite()函数介绍
3. 示例代码
1. PNG图像简单介绍
PNG是20世纪90年代开发的一种取代GIF和TIFF的图像文件存储格式,适用于网络传播的轻便图片文件格式。
上面这么多特性,本文中使用到的是PNG的透明性。
PNG的文件结构
PNG图像格式由文件署名和数据块组成。
PNG文件署名有8字节,用来识别PNG格式,所有的PNG图片文件内容开头都有文件署名。这8个字节的分别是:89H 50H 4EH 47H 0DH 0AH 1AH 0AH
利用文件头标志判断文件类型 (mythsman.com)列举了更多文件格式的文件头标志。
PNG数据块定义了两种类型的数据块,一种是称为关键数据块,是必需的数据块,另一种叫做辅助数据块,是可选的数据块。每个数据块都包含长度、数据块类型、数据块数据、循环冗余检测四个部分。
更详细的信息参考:PNG文件格式详解 - maxiongying - 博客园 (cnblogs.com)
2. cv::imwrite()函数介绍
cv::imwrite()函数是Opencv提供的保存图片的函数,函数原型:
- bool cv::imwrite(
- const string& filename,
- cv::InputArray image,
- const vector<int>& params =vector<int>());
参数params是表示为特定格式保存的参数编码,是STL vector类型,具体内容为:一系列的参数ID以及与该参数对应的参数值。对于本文,保存PNG格式,那么参数params可以这样定义:
- vector<int> compression_params;
- compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
- compression_params.push_back(9);
CV_IMWRITE_PNG_COMPRESSION表示压缩PNG;9表示压缩的强度,值越大意味着更多的压缩,范围是0~9,默认是3。
3. 示例代码
- #include
- #include
-
- using namespace std;
- using namespace cv;
-
- int main()
- {
- // 创建带有alpha(透明)通道的Mat
- cv::Mat pngAlphaMat(480, 640, CV_8UC4);
- cv::Mat pngMat(480, 640, CV_8UC3);
-
- for (int i = 0; i < pngAlphaMat.rows; i++)
- {
- for (int j = 0; j < pngAlphaMat.cols; j++)
- {
- Vec4b &rgba = pngAlphaMat.at
(i, j); - Vec3b &rgb = pngMat.at
(i, j); -
- rgba[0] = UCHAR_MAX;
- rgba[1] = saturate_cast
((float(pngAlphaMat.cols - j) / ((float)pngAlphaMat.cols))*UCHAR_MAX); - rgba[2] = saturate_cast
((float(pngAlphaMat.rows - i) / ((float)pngAlphaMat.rows))*UCHAR_MAX); - rgba[3] = saturate_cast
(0.5 * (rgba[1] + rgba[2])); -
- rgb[0] = saturate_cast
((float(pngMat.cols - j) / ((float)pngMat.cols))*UCHAR_MAX); - rgb[1] = saturate_cast
((float(pngMat.rows - i) / ((float)pngMat.rows))*UCHAR_MAX); - rgb[2] = saturate_cast
(0.5 * (rgb[1] + rgb[2])); -
- }
- }
-
- vector<int> compression_params;
- compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
- compression_params.push_back(9);
- cv::imwrite("透明Alpha图.png", pngAlphaMat, compression_params);
- cv::imwrite("不透明图.png", pngMat, compression_params);
-
- cv::imshow("透明PNG图", pngAlphaMat);
- cv::imshow("非透明PNG图", pngMat);
-
- cv::waitKey(0);
-
- return 0;
- }
保存的图片:
