在使用 32 位 TBitmap 时,我从 Canvas.Pixels 切换到 ScanLine。
然后我将值设置为红色,却发现它显示为蓝色。
知道为什么吗?
这是代码摘录:
procedure TForm1.FormPaint(Sender: TObject);
var
varBitmap: TBitmap;
pLock: PIntegerArray;
iColor: integer;
begin
varBitmap := TBitmap.Create;
varBitmap.PixelFormat := pf32bit;
varBitmap.Width := 800;
varBitmap.Height := 600;
// Set Pixels to Red
varBitmap.Canvas.Pixels[0, 0] := $0000FF;
// Shows $FF0000 (blue)
pLock := varBitmap.ScanLine[0];
iColor := pLock[0];
ShowMessageFmt('%x', [iColor]);
// Set ScanLine to Red
pLock[0] := $0000FF;
// Displays a blue pixel
Canvas.Draw(0, 0, varBitmap);
end;
似乎 TColor 与内存中的不一样,但这没有意义。
欢迎任何建议。 ;)
VCL 位图类,TBitmap
是 Windows 本机设备独立位图 (DIB) 的包装器。这些位图对象可以存储多种不同像素格式的位图。它们可以是单色的,每像素一位,最多每像素 32 位,这是您正在使用的格式。它们还可以用于存储基于调色板的位图,其中每个像素都保存颜色表的索引。
访问您引用的像素数据的两种方法是Pixels
的财产TCanvas
和ScanLine
的财产TBitmap
.
The Pixels
的财产TCanvas
是 GDI 的包装GetPixel and SetPixel功能。这些是运行在的高级函数COLORREF价值观。的文档COLORREF says:
低位字节包含红色相对强度的值;第二个字节包含绿色值;第三个字节包含蓝色值。高位字节必须为零。单字节的最大值为 0xFF。
换句话说,一个COLORREF
value 有固定的像素颜色编码方式。这GetPixel
and SetPixel
函数主要处理固定值之间的转换COLORREF
形式和底层原始位图像素数据。另请注意,COLORREF
不能代表alpha值。这COLORREF
值的格式为 $00BBGGRR。
另一方面,ScanLine
的财产TBitmap
返回一个指向底层 DIB 对象的原始像素数据的指针。您此处使用的数据是 32bpp 像素数据,该数据的约定是以 $AARRGGBB 格式存储。窗户文档对于 32bpp 数据说:
位图最多有 2^32 种颜色。如果 BITMAPINFOHEADER 的 biCompression 成员为 BI_RGB,则 BITMAPINFO 的 bmiColors 成员为 NULL。位图数组中的每个 DWORD 代表像素的蓝色、绿色和红色的相对强度。蓝色的值位于最低有效 8 位中,随后是绿色和红色各 8 位。每个 DWORD 中的高字节不被使用。
所以事实上这段文字是不正确的并且已经过时了。每个中的高字节DWORD
事实上,如果使用的话,就是 alpha 通道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)