【OpenCV】生成透明的PNG图像

news/2024/10/30 9:34:12/

本文从三个方面讲解如何使用opencv的cv::imwrite()函数生成透明/不透明的PNG图像:

目录

1. PNG图像简单介绍

PNG的文件结构

2. cv::imwrite()函数介绍

3.  示例代码


1. PNG图像简单介绍

PNG是20世纪90年代开发的一种取代GIF和TIFF的图像文件存储格式,适用于网络传播的轻便图片文件格式。

  • PNG图像具有流式读写性,允许连续读出和写入图像数据,因此适用于网络传播。
  • PNG图像可以逐次逼近显示,这种特性可以使在通信链路上传输图像文件的同时就在终端上显示图像,把整个轮廓显示出来之后逐步显示图像的细节。
  • PNG图像可以是透明的,可以使图像中某些部分不显示出来,用来创建一些特色的图像。
  • PNG图像独立于计算机软硬件环境,使用无损压缩,可以在一个文件中存储多幅图像。

上面这么多特性,本文中使用到的是PNG的透明性。

PNG的文件结构

PNG图像格式由文件署名和数据块组成。

PNG文件署名有8字节,用来识别PNG格式,所有的PNG图片文件内容开头都有文件署名。这8个字节的分别是:89H 50H 4EH 47H 0DH 0AH 1AH 0AH

  • 89H:用于检测传输系统是否支持8位的字符编码,用以减少将文本文件被错误的识别成PNG文件的机会;
  • 50H 4EH 47H:PNG每个字母对应的ASCII,识别出是PNG文件;
  • 0DH 0AH:DOS风格的换行符,用于DOS-Unix数据的换行符转换;
  • 1AH:在DOS命令行下,用于阻止文件显示的文件结束符;
  • 0AH:Unix风格的换行符,用于Unix-DOS换行符的转换;

利用文件头标志判断文件类型 (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 <iostream>
#include <opencv.hpp>using namespace std;
using namespace cv;int main()
{// 创建带有alpha(透明)通道的Matcv::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<Vec4b>(i, j);Vec3b &rgb = pngMat.at<Vec3b>(i, j);rgba[0] = UCHAR_MAX;rgba[1] = saturate_cast<uchar>((float(pngAlphaMat.cols - j) / ((float)pngAlphaMat.cols))*UCHAR_MAX);rgba[2] = saturate_cast<uchar>((float(pngAlphaMat.rows - i) / ((float)pngAlphaMat.rows))*UCHAR_MAX);rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));rgb[0] = saturate_cast<uchar>((float(pngMat.cols - j) / ((float)pngMat.cols))*UCHAR_MAX);rgb[1] = saturate_cast<uchar>((float(pngMat.rows - i) / ((float)pngMat.rows))*UCHAR_MAX);rgb[2] = saturate_cast<uchar>(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;
}

保存的图片:


http://www.ppmy.cn/news/214599.html

相关文章

如何使QTextEdit背景透明

前边的文章http://blog.csdn.net/NRC_DouNingBo/archive/2010/04/28/5540427.aspx介绍了如何给QTextEdit加背景图片&#xff0c;但是由于图片也会跟着翻屏&#xff0c;所以用了一种折中的办法就是&#xff1a;将QTextEdit设置为透明&#xff0c;而后在其后边的窗口的该位置处刷…

MFC窗口透明化以及透明穿透

MFC编程时&#xff0c;有时候我们需要实现窗口透明化&#xff0c;可以通过SetLayeredWindowAttributes设置窗口透明色和透明度来实现窗口透明化。而要使窗口拥有透明效果,前提是窗口要有WS_EX_LAYERED扩展属性&#xff0c;需用SetWindowLong设置窗口支持拓展风格。 一、窗口透…

跨5合并dnf无限连接服务器,不妨一试!跨5等跨区卡登陆卡黑屏解决办法分享

今日我们怀着激动的心情&#xff0c;在10点登陆游戏(跨5)&#xff0c;发现跨区并未更新&#xff0c;频道比原来还少了许多&#xff0c;登陆还。出现卡登陆和卡黑屏。 故障分析&#xff1a; 经过多次尝试&#xff0c;我们发现本次全服跨区更新&#xff0c;游戏客户端和服务器配置…

dnf一换线就服务器不稳定,DNF:史派克做事了!换线黑屏已解决,玩家点取消可返回其它频道...

地下城历经十年&#xff0c;装备换了一批又一批&#xff0c;全民紫装到了全民史诗&#xff0c;但不变的也有那就是“鬼剑士”与地下城&#xff0c;还有那备受吐槽的“掉线城”&#xff0c;策划因为这个一直背锅&#xff0c;只更新节日礼包&#xff0c;就不更新对应优化改版&…

dnf打开显示进入服务器黑屏,win7系统玩地下城与勇士(DNF)出现黑屏怎么办

地下城与勇士是一款2D卷轴式横版格斗过关网络游戏&#xff0c;深受广大游戏玩家喜爱&#xff0c;在游戏过程中难免遇到一些奇怪的问题&#xff0c;比如之前小编分享Win7系统玩地下城与勇士提示图表系统组件失败怎么办。但是最近有用户说win7 64位系统玩地下城与勇士(DNF)出现黑…

神州炫龙毁灭者DC pro 和 DD pro_1.05.11RHA3原厂BIOS

支持八代I3 8100 8350 ,八代I5 8500需要屏蔽针脚&#xff0c;如图

炫龙笔记本组合快捷键

快捷键的使用说明&#xff1a;F1---一键开强冷F2---一键锁触摸板F3---开启或关闭CPU智能睿频&#xff08;超频&#xff09; FNF1----关闭或开启触摸板FNF2----切换外接显示器FNF3----关闭无线wifiFNf4----开启或关闭摄像头FNF11---开启一键超频FNF12---开启或关闭键盘背光灯 转…