Jar*_*rno 4 delphi bitmap pixels scanline
使用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;
Run Code Online (Sandbox Code Playgroud)
似乎TColor与内存中的内容不同,但这没有任何意义.
欢迎任何建议.;)
VCL位图类TBitmap是Windows本机设备独立位图(DIB)的包装器.这些位图对象可以以各种不同的像素格式存储位图.它们可以是单色的,每像素一位,每像素高达32位,即您使用的格式.它们还可用于存储基于调色板的位图,其中每个像素将索引保存到颜色表中.
访问您引用的像素数据的两种方法是Pixels属性TCanvas和ScanLine属性TBitmap.
该Pixels属性TCanvas是GDI GetPixel和SetPixel函数的包装器.这是一个以COLORREF价值观为基础的高级功能.文档COLORREF说:
低位字节包含红色相对强度的值; 第二个字节包含绿色值; 第三个字节包含蓝色的值.高位字节必须为零.单个字节的最大值为0xFF.
换句话说,COLORREF值具有对像素颜色进行编码的固定方式.的GetPixel和SetPixel功能多处理固定之间的变换COLORREF形式和下面的原始位图像素数据.另请注意,a COLORREF不能表示alpha值.该COLORREF值为$ 00BBGGRR格式.
另一方面,该ScanLine属性TBitmap返回指向底层DIB对象的原始像素数据的指针.您在这里使用的数据是32bpp像素数据,该数据的约定是它以$ AARRGGBB格式存储.32bpp数据的Windows 文档说:
位图最多有2 ^ 32种颜色.如果BITMAPINFOHEADER的biCompression成员是BI_RGB,则BITMAPINFO的bmiColors成员为NULL.位图数组中的每个DWORD表示像素的蓝色,绿色和红色的相对强度.蓝色的值是最低有效8位,后面是绿色和红色各8位.不使用每个DWORD中的高字节.
所以实际上这个文本不正确并且已经过时了.DWORD事实上,每个高字节都是alpha通道,如果使用的话.