【发布时间】:2017-08-05 17:22:06
【问题描述】:
当我尝试使用 QImage 构造函数从 reinterpret_cast<uchar*>(quint32*) 创建 ARGB32 QImage 时,Image 会丢失其颜色和 alpha 通道,并且生成的 QImage 是灰度的!
如果我尝试以灰度显示,灰度图像会按预期显示。所以我知道 quint32 数组的 ushort 数据的缩放和索引很顺利,但是出了什么问题?
A Qt forum post 建议按照我的方式进行操作(据我所见),但自该版本的 Qt 以来行为可能发生了变化? (我使用的是 Qt 5.9)
我意识到文档说:
数据必须是 32 位对齐的,并且图像中数据的每个扫描线 也必须是 32 位对齐的。
但我希望 quint32 即使在 reinterpret_cast<uchar*>() 之后也是 32 位对齐的?
现在详情: 我正在将计算结果(具有无符号短值的数组)转换为半透明的蓝色到绿色到红色的图像,如下所示:
inline uchar val_to_blue(const double val) {
if (val > 0.5)
return 0;
else if (val < 0.25)
return 255;
else // x={.5,...,.25}:a=255/(.25-.5)=-4*255 & b=-255*0.5/(0.25-0.5)=4/2*255=2*255
return (uchar)(val * -4.0 * 255.0) + 2 * 255;
}
inline uchar val_to_green(const double val) {
if (val > 0.25 && val < 0.75)
return 255;
else if (val < 0.25)// x={0,...,.25}:a=255/(.25-0)=4*255 & b=-255*0/(0.25-0)=0
return (uchar)(val * 4.0 * 255.0);
else // if (val > .75) // x={.75,...,1}:a=255/(.75-.5)=4*255 & b=-255*0.5/(0.75-0.5)=-4/2*255=-2*255
return (uchar)(val * -4.0 * 255.0) - 2 * 255;
}
inline uchar val_to_red(const double val) {
if (val < 0.5)
return 0;
if (val > 0.75)
return 255;
else // x={0.5,...,0.75}:a=255/(0.75-0.5)=4*255 & b=-255*0.5/(0.75-0.5)=-4/2*255=-2*255
return (uchar)(val * 4.0 * 255.0) - 2 * 255;
}
inline QRgb val_to_rgba_scale(const double val) {
return qRgba( // ax+b={0,...,255} for x={i,...,j}, a=255/(j-i), b= -255i/(j-i)
val_to_blue(val),
val_to_green(val),
val_to_red(val),
(uchar)(val * 81)
);
}
其中val 是从 ushort 数据缩放的 0 和 1 之间的双精度数。
每个QRgb 值都存储在quint32 数组的相应索引处,如下所示:
if (m_pData[i*m_iWidth + j] >= uppVal)
tmpData[tmpIdx] = 0x45ff0000;
else if (m_pData[i*m_iWidth + j] <= lowVal)
tmpData[tmpIdx] = 0x00000000;
else
tmpData[tmpIdx] = val_to_rgba_scale((m_pData[i*m_iWidth + j] - lowVal) / (double)winWidth);
其中(m_pData[i*m_iWidth + j] - lowVal) / (double)winWidth是ushort-to-double缩放方法。
这是在 for 循环中完成的。
最后我尝试用以下方法构建图像:
QImage tmpQImage = QImage(reinterpret_cast<unsigned char*>(tmpData), m_iWidth, m_iHeight, QImage::Format_ARGB32);
但这并没有像我预期的那样工作,因为tmpQImage.allGray() 在之后立即调用时返回 true!
我做错了什么,我应该怎么做才能创建 ARGB 图像并同时保留颜色和 Alpha 通道?
【问题讨论】:
-
疑难解答建议:尝试用二维for循环和QImage的“putpixel”方法逐像素生成图像,看看是否正确。如果是正确的,那么将这个正确图像中的原始数据与灰度图像中的数据进行比较。如果不对,那么问题一定出在原始的原始图像数据中……