首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >德尔福TBitmap -为什么像素和ScanLine不同?

德尔福TBitmap -为什么像素和ScanLine不同?
EN

Stack Overflow用户
提问于 2014-03-10 02:32:50
回答 2查看 4.3K关注 0票数 4

在使用32位TBitmap时,我从Canvas.Pixels切换到了ScanLine。

然后,我将值设置为Red,结果发现它显示为蓝色。

知道为什么吗?

下面是一个代码摘录:

代码语言:javascript
复制
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似乎与内存中的内容不一样,但这是毫无意义的。

欢迎任何建议。;)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-10 03:25:17

32位像素数据采用$AARRGGBB格式。您正在设置蓝色组件,而不是红色组件。使用$FF0000而不是$0000FF。或者更好的是,使用RGB()函数。

票数 5
EN

Stack Overflow用户

发布于 2014-03-10 13:24:45

VCL位图类,TBitmap是一个包装的Windows本机设备独立位图(DIB)。这些位图对象可以以多种不同的像素格式存储位图。它们可以是单色的,每像素一位,最多32位/像素,这是您正在使用的格式。它们还可以用于存储基于调色板的位图,其中每个像素都将索引保存到颜色表中。

访问所引用的像素数据的两种方法是TCanvasPixels属性和TBitmapScanLine属性。

Pixels属性TCanvas是GDI、GetPixelSetPixel函数的包装器。这是一个在COLORREF值上操作的高级函数.COLORREF的文档说:

低阶字节包含一个相对强度为红色的值;第二个字节包含一个绿色值;第三个字节包含一个蓝色值。高阶字节必须为零.单个字节的最大值为0xFF。

换句话说,COLORREF值有固定的编码像素颜色的方式。GetPixelSetPixel函数很大程度上处理固定的COLORREF表单和底层原始位图像素数据之间的转换。还请注意,COLORREF不能表示alpha值。COLORREF值为$00BBGGRR格式。

另一方面,ScanLine属性TBitmap返回指向基础DIB对象的原始像素数据的指针。这里处理的数据是32 you像素数据,该数据的约定是以$AARRGGBB格式存储。Windows32bpp的documentation数据显示:

位图最多有2^32种颜色。如果BITMAPINFOHEADER的biCompression成员是BI_RGB,则BITMAPINFO的bmiColors成员为NULL。位图数组中的每个DWORD表示一个像素的蓝色、绿色和红色的相对强度。蓝色的值是最小的8位,其次是绿色和红色的8位。不使用每个DWORD中的高字节。

因此,事实上,这篇文章是不正确的和过时的。如果使用的话,每个DWORD中的高字节实际上是alpha通道。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22291162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档