gpt4 book ai didi

delphi - 在Delphi中,TBitmap.Monochrome和.PixelFormat如何影响.ScanLine的格式?

转载 作者:行者123 更新时间:2023-12-03 14:52:35 30 4
gpt4 key购买 nike

我想将具有 Mono8 格式(单色 8 位)位图的给定缓冲区分配给位图。然后,我将生成的位图分配给 TImage 组件来显示它。这些图片是显示结果的屏幕截图。

下面的代码可以工作,但看起来有点浪费:

procedure CopyToBitmapMono824(_Buffer: PByte; _Bmp: TBitmap);
var
y: Integer;
x: Integer;
ScanLine: PdzRgbTripleArray;
begin
for y := 0 to _Bmp.Height - 1 do begin
ScanLine := _Bmp.ScanLine[y];
for x := 0 to _Bmp.Width - 1 do begin
// monochrome: all 3 colors set to the same value
ScanLine[x].Red := _Buffer^;
ScanLine[x].Green := _Buffer^;
ScanLine[x].Blue := _Buffer^;
Inc(_Buffer);
end;
end;
end;

// [...]
fBmp.PixelFormat := pf24Bit;
FBmp.Monochrome := False;
CopyToBitmap(Buffer, fBmp);

correct gray scale image

我宁愿使用我尝试过的 pf8Bit 格式的位图:

procedure CopyToBitmapMono8(_Buffer: PByte; _Bmp: TBitmap);
var
y: Integer;
x: Integer;
ScanLine: PByteArray;
begin
for y := 0 to _Bmp.Height - 1 do begin
ScanLine := _Bmp.ScanLine[y];
for x := 0 to _Bmp.Width - 1 do begin
ScanLine[x] := _Buffer^;
Inc(_Buffer);
end;
end;
end;

// [...]
FBmp.PixelFormat := pf8bit;
FBmp.Monochrome := False; // I also tried Monochrome := true
CopyToBitmapMono8(Buffer, FBmp)

如果 MonoChrome 为 true,则图片只有预期宽度的 1/4 左右,其余部分为白色。

Mono + white

如果 MonoChrome 为 false,则图片具有预期宽度,但左侧 1/4 是单色,其余部分包含假颜色。

Mono+false colors

我显然错过了一些东西,但是什么呢?

编辑:位图仅为预期大小的 1/4 的效果显然是在显示之前将其转换为 JPEG 进行保存的副作用(我在上面没有显示代码,我很抱歉)。所以问题很简单,我没有为位图设置单色调色板。

最佳答案

Monochromepf1bit 位图有意义。

否则,Monochrome := True 将位图格式更改为 DDB (pfDevice)。您的屏幕是 32 位,因此调用 Scanline 会导致 DibNeeded 调用并转换为 32 位,并使用函数 CopyToBitmapMono8(适用于 8-位)仅占屏幕的 1/4。

为了正确使用 8 位位图,您必须将标准的奇怪调色板(在最后一张图像的右侧部分使用)更改为灰色。

procedure CopyToBitmapMono8(_Buffer: PByte; _Bmp: TBitmap);
var
y: Integer;
x: Integer;
ScanLine: PByteArray;
begin
for y := 0 to _Bmp.Height - 1 do begin
ScanLine := _Bmp.ScanLine[y];
for x := 0 to _Bmp.Width - 1 do begin
ScanLine[x] := _Buffer^;
Inc(_Buffer);
end;
end;
end;

var
FBmp: TBitmap;
Buffer: PbyteArray;
i: integer;
begin
GetMem(Buffer, 512 * 100);
for i := 0 to 512 * 100 - 1 do
Buffer[i] := (i and 511) div 2; // gray gradient

FBmp := Tbitmap.Create;
FBmp.Width := 512;
FBmp.Height := 100;
FBmp.PixelFormat := pf8bit;
CopyToBitmapMono8(PByte(Buffer), FBmp);
Canvas.Draw(0, 0, FBmp);

//now right approach
FBmp.Palette := MakeGrayPalette; // try to comment
CopyToBitmapMono8(PByte(Buffer), FBmp);
Canvas.Draw(0, 110, FBmp);

end;

function TForm1.MakeGrayPalette: HPalette;
var
i: integer;
lp: TMaxLogPalette;
begin
lp.palVersion := $300;
lp.palNumEntries := 256;
for i := 0 TO 255 do begin
lp.palPalEntry[i].peRed := i;
lp.palPalEntry[i].peGreen := i;
lp.palPalEntry[i].peBlue := i;
lp.palPalEntry[i].peFlags := PC_RESERVED;
end;
Result := CreatePalette(pLogPalette(@lp)^);
end;

enter image description here

And example at efg2 page

关于delphi - 在Delphi中,TBitmap.Monochrome和.PixelFormat如何影响.ScanLine的格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51067460/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com