我正在寻找如何使用GDI(而不是GDI)将32位位图转换为灰度的简单解决方案.是否有可能,例如通过改变位图的托盘或什么?
当然在Delphi中有很多像this one这样的例子,但是我正在寻找一个WinAPI函数,它可以在没有迭代的情况下执行此操作.
解决方法@H_502_6@
我没有找到任何单一的GDI功能.大卫在评论中提到的最简单的方法是扫描每一行并计算像素颜色.您正在寻找的可能是
luminance
公式.
这个公式的变化很少,在下面的例子中,我使用了ITU
推荐的那个,参见this document
第2.5.1节.正如我在某处发现的那样,使用这个公式,例如即使是众所周知的Adobe Photoshop.以下代码示例仅支持并期望24位像素格式位图作为输入:
procedure BitmapGrayscale(ABitmap: TBitmap);
type
PPixelRec = ^TPixelRec;
TPixelRec = packed record
B: Byte;
G: Byte;
R: Byte;
end;
var
X: Integer;
Y: Integer;
Gray: Byte;
Pixel: PPixelRec;
begin
for Y := 0 to ABitmap.Height - 1 do
begin
Pixel := ABitmap.ScanLine[Y];
for X := 0 to ABitmap.Width - 1 do
begin
Gray := Round((0.299 * Pixel.R) + (0.587 * Pixel.G) + (0.114 * Pixel.B));
Pixel.R := Gray;
Pixel.G := Gray;
Pixel.B := Gray;
Inc(Pixel);
end;
end;
end;
luminance
公式.
这个公式的变化很少,在下面的例子中,我使用了ITU
推荐的那个,参见this document
第2.5.1节.正如我在某处发现的那样,使用这个公式,例如即使是众所周知的Adobe Photoshop.以下代码示例仅支持并期望24位像素格式位图作为输入:
procedure BitmapGrayscale(ABitmap: TBitmap); type PPixelRec = ^TPixelRec; TPixelRec = packed record B: Byte; G: Byte; R: Byte; end; var X: Integer; Y: Integer; Gray: Byte; Pixel: PPixelRec; begin for Y := 0 to ABitmap.Height - 1 do begin Pixel := ABitmap.ScanLine[Y]; for X := 0 to ABitmap.Width - 1 do begin Gray := Round((0.299 * Pixel.R) + (0.587 * Pixel.G) + (0.114 * Pixel.B)); Pixel.R := Gray; Pixel.G := Gray; Pixel.B := Gray; Inc(Pixel); end; end; end;