2014-08-28 67 views
0

我想要访问QImage中的图像颜色。从RGB32和索引类型的图像获取图像颜色信息

,我发现在文档大多数是基于扫描线功能的方法...

我试着和它的工作......在RGB32图像。使用精确的方法获取8位索引或单色图像的颜色数据时,我出现了令人惊讶的不愉快结果。

这是我的代码:

// note RGBTriple is a struct containing unsigned R, G, B 
// rgbImage.pixels is a RGBTriple* array 

RGBTriple* pTriple = rgbImage.pixels; 
for (int y = 0; y < source.height(); y++) 
{ 
    const unsigned char* pScanLine = source.scanLine(y); 
    for (int x = 0; x < source.width(); x++) 
    { 
     QRgb* color = (QRgb*)pScanLine; 
     pTriple->R = qRed(*color); 
     pTriple->G = qGreen(*color); 
     pTriple->B = qBlue(*color); 
     ++pTriple; 
     pScanLine += 4; 
    } 
} 

运行相同的代码与8位图像索引或单色,我在创造越来越颜色有误差。该文件说scanline是32b的倍数 - 但由于这是8和2的倍数,我不认为这会是一个问题。

一旦我发现,我没有得到正确的结果,为所有类型的输入图像,我把它改成

RGBTriple* pTriple = rgbImage.pixels; 
for (int y = 0; y < source.height(); y++) 
{ 
    for (int x = 0; x < source.width(); x++) 
    { 
     pTriple->R = qRed(source.pixel(x, y)); 
     pTriple->G = qGreen(source.pixel(x, y)); 
     pTriple->B = qBlue(source.pixel(x, y)); 
     ++pTriple; 
    } 
} 

完美的作品......我不知道它是较慢或将有其他意外的行为?毕竟,我使用pixel()函数 - 即使是在索引图像上 - 以获取颜色信息,实际上应该以不同的方式存储......看起来应该会失败...

有没有办法让第一个版本,使用扫描线,适用于其他图像类型?

为什么看起来像使用scanline来获取数据是首选方法?

+1

关于“慢”,至少调用'pixel'只有一次和存储返回值的临时变量... – hyde 2014-08-28 17:42:28

回答

1

我试过了,它在RGB32图像上工作。当我使用确切的方法获取位图索引或单色图像的颜色数据时,我出人意料地发现了令人不快的结果。

你不应该感到惊讶,因为索引和单色图像不同格式。您发布的第一个代码片段是基于如何将RGB32(和RGB32)铺设在内存中的知识。

想一想。在单色图像R=G=B。所以只有一个通道需要保存在内存中。

如果你的目标是获得内部rgbImage.pixels使用QImage::convertToFormat() RGB图像:

QImage source; 
QImage dest = source.convertToFormat(QImage::Format_RGB888); 
memcpy(rgbImage.pixels, dest.bits(),dest.byteCount()); 
+0

什么将是rgbImage.pixels的内容?它会变成一个无符号字符数组*,每种颜色都有一个字符 - 所以字节数为size的3倍? – Thalia 2014-08-28 16:42:39

+0

是的,它是一个arrawy rgbrgbrgb ....其中每种颜色都是无符号字符。 rgb24的dest.byteCount已经是3 * width *高度字节。我期望rgbImage.pixels是相同的大小。 – UmNyobe 2014-08-28 18:43:07