在MFC中转化32位深度带透明通道PNG图像到24位深度MAT图像遇到的问题。

时间:2020-11-28 03:35:42
int nWidth = cimage.GetWidth();
int nHeight = cimage.GetHeight();
if (4 == nChannels)
{
mat.create(nHeight, nWidth, CV_8UC3);
}


//拷贝数据


uchar* pucRow; //指向数据区的行指针
uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
int nStep = cimage.GetPitch(); //每行的字节数,注意这个返回值有正有负


for (int nRow = 0; nRow < nHeight; nRow++)
{
pucRow = (mat.ptr<uchar>(nRow));
for (int nCol = 0; nCol < nWidth; nCol++)
{
if (1 == nChannels)
{
pucRow[nCol] = *(pucImage + nRow * nStep + nCol);
}
else if (3 == nChannels)
{
for (int nCha = 0; nCha < 3; nCha++)
{
pucRow[nCol * 3 + nCha] = *(pucImage + nRow * nStep + nCol * 3 + nCha);
}
}
else if (4 == nChannels)
{
for (int nCha = 0; nCha < 3; nCha++)
{
pucRow[nCol * 3 + nCha] = *(pucImage + nRow * nStep + nCol * 4 + nCha);
}
}
}
}
这是我的程序,如果是4通道PNG图的话运行后无法得到图像,如果PNG是按照BGRA来排列的话我感觉应该是可以的啊不知道问题是出在哪里

3 个解决方案

#1


百度搜相关关键字。

#2


我百度了很久都没有看到有关带透明通道的PNG CImage类转MAT去除透明通道的问题,当然我也可以用“百度搜相关关键字。”来回答这里的任何问题,没毛病兄弟。

#3


问题已解决,虽然不知道我上面代码在哪里有问题;
CImage fcimage;
fcimage.Create(image.GetWidth(), image.GetHeight(), 24);
if (image.GetBPP() / 8 == 4)
{
int i;
int j;
for (i = 0; i < image.GetWidth(); i++)
{
for (j = 0; j < image.GetHeight(); j++)
{
byte *pByte = (byte *)image.GetPixelAddress(i, j);
byte *ppngByte = (byte*)fcimage.GetPixelAddress(i, j);
ppngByte[0] = pByte[0] * pByte[3] / 255;
ppngByte[1] = pByte[1] * pByte[3] / 255;
ppngByte[2] = pByte[2] * pByte[3] / 255;

}
}
}
这是4通道转为3通道CImage图的
同理把for循环里改成ppngByte[0] = ((pByte[0]+ pByte[1]+ pByte[2])/3) * pByte[3] / 255;就是单通道的了。
思路完全一样就是改了个顺序,不知道为什么不对,奇怪

#1


百度搜相关关键字。

#2


我百度了很久都没有看到有关带透明通道的PNG CImage类转MAT去除透明通道的问题,当然我也可以用“百度搜相关关键字。”来回答这里的任何问题,没毛病兄弟。

#3


问题已解决,虽然不知道我上面代码在哪里有问题;
CImage fcimage;
fcimage.Create(image.GetWidth(), image.GetHeight(), 24);
if (image.GetBPP() / 8 == 4)
{
int i;
int j;
for (i = 0; i < image.GetWidth(); i++)
{
for (j = 0; j < image.GetHeight(); j++)
{
byte *pByte = (byte *)image.GetPixelAddress(i, j);
byte *ppngByte = (byte*)fcimage.GetPixelAddress(i, j);
ppngByte[0] = pByte[0] * pByte[3] / 255;
ppngByte[1] = pByte[1] * pByte[3] / 255;
ppngByte[2] = pByte[2] * pByte[3] / 255;

}
}
}
这是4通道转为3通道CImage图的
同理把for循环里改成ppngByte[0] = ((pByte[0]+ pByte[1]+ pByte[2])/3) * pByte[3] / 255;就是单通道的了。
思路完全一样就是改了个顺序,不知道为什么不对,奇怪