Jav*_*vid 4 delphi image bitmap grayscale scanline
嗨,这里是我的代码:
procedure TForm4.Button1Click(Sender: TObject);
var
png: TPNGImage;
data: PRGBQarray;
p: ^tagRGBQuad;
i, o: integer;
begin
png := TPNGImage.Create;
try
png.LoadFromFile('C:\Untitled.png');
for o := 1 to 100 do
begin
data:=png.Scanline[o];
for I := 1 to 400 do
begin
p := @data^[i];
p.rgbGreen := p.rgbBlue;
p.rgbRed := p.rgbGreen;
end;
end;
img.picture.Assign(png);
finally
png.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
它不起作用,它使pic杂乱,我确定这是因为rgbReserved.我该怎么办?
这是如何灰化位图.(并且,是的,如果你想要对PNG进行灰化,你首先需要从中获取位图数据.我认为VCL会为你做这个.)
type
PRGB32Array = ^TRGB32Array;
TRGB32Array = packed array[0..MaxInt div SizeOf(TRGBQuad)-1] of TRGBQuad;
procedure MakeGrey(Bitmap: TBitmap);
var
w, h: integer;
y: Integer;
sl: PRGB32Array;
x: Integer;
grey: byte;
begin
Bitmap.PixelFormat := pf32bit;
w := Bitmap.Width;
h := Bitmap.Height;
for y := 0 to h - 1 do
begin
sl := Bitmap.ScanLine[y];
for x := 0 to w - 1 do
with sl[x] do
begin
grey := (rgbBlue + rgbGreen + rgbRed) div 3;
rgbBlue := grey;
rgbGreen := grey;
rgbRed := grey;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
样品用法:
procedure TForm4.Button1Click(Sender: TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
try
bm.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\Porträtt, litet, kvadratiskt.bmp');
MakeGrey(bm);
Canvas.Draw(0, 0, bm);
finally
bm.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
安德烈亚斯的答案会给你一个好的,快速的近似值,但你会失去一些质量,因为红色,绿色和蓝色不会在人眼中以相同的强度混合.如果你想"正确",而不是
grey := (rgbBlue + rgbGreen + rgbRed) div 3;
试试这个:
grey := round(rgbRed * .3) + round(rgbGreen * .59) + round(rgbBlue * .11);
你可以在简单的平均值上获得一点性能,但除非你的图像非常大,否则它可能不会引人注意.