gpt4 book ai didi

delphi - 使用 ScanLine 快速交换红/蓝字节的方法

转载 作者:行者123 更新时间:2023-12-01 23:35:47 30 4
gpt4 key购买 nike

目前,我循环播放 Canvas.Pixels[]属性并读取 Canvas 上的每个像素以交换红色/蓝色字节(出于特定原因)。然而,每张图片平均需要 2 秒,而且我有超过 8,000 张图片需要转换(一整夜)。我知道我可以使用 ScanLine 的方法更快地完成此任务,但我对 ScanLine 一无所知- 这是一个比我能接受的低得多的编码水平。实现这一目标最快的方法是什么?我愿意等待一段时间来完成这件事,但如果我能将时间缩短一半或更多,那就太好了。

现在,这是我使用的程序:

procedure SwapBytes(var Bmp: TBitmap);
var
X, Y: Integer;
R, G, B: Byte;
C: TColor;
begin
for Y := 0 to Bmp.Height - 1 do begin
for X := 0 to Bmp.Width - 1 do begin
C:= Bmp.Canvas.Pixels[X,Y];
R:= GetRValue(C);
G:= GetGValue(C);
B:= GetBValue(C);
Bmp.Canvas.Pixels[X,Y]:= RGB(B, G, R)
end;
end;
end;

添加注释:对 8,000 多个图像的初始转换是我需要此功能的第一步。但是,我还将在我们的软件中使用相同的功能,根据需要自动当场转换任何图像。因此第三方转换器将无法工作,因为我无法将其分发给我们的客户。

最佳答案

我会尝试如下操作。此版本仅适用于 24 位位图:

procedure SwapRedBluePixels(ABitmap: TBitmap);
var
X: Integer;
Y: Integer;
Red: Byte;
Pixel: PRGBTriple;
begin
// check for the bit depth, it must be 24-bit if you use PRGBTriple pointer
// for line scan; if it wouldn't the iterated line pointers would point to
// another place in the memory
if ABitmap.PixelFormat <> pf24bit then
begin
ShowMessage('Your bitmap has color depth different from 24-bit');
Exit;
end;
// iterate through the image vertically
for Y := 0 to (ABitmap.Height - 1) do
begin
// access the line of pixels and get the pointer to the first pixel of
// that line
Pixel := ABitmap.ScanLine[Y];
// iterate through the scanned line pixels horizontally
for X := 0 to (ABitmap.Width - 1) do
begin
// store the pixel's red channel value
Red := Pixel.rgbtRed;
// modify the pixel's red channel value
Pixel.rgbtRed := Pixel.rgbtBlue;
// modify the pixel's blue channel value
Pixel.rgbtBlue := Red;
// increment to get the next pixel pointer of the scanned line
Inc(Pixel);
end;
end;
end;

更新 2:

此版本适用于 24 位和 32 位位图:

procedure SwapRedBluePixels(ABitmap: TBitmap);
var
X: Integer;
Y: Integer;
Red: Byte;
Size: Integer;
Pixels: PByteArray;
begin
// check the color depth and set the size of the pixel arrangement
case ABitmap.PixelFormat of
pf24bit: Size := SizeOf(TRGBTriple);
pf32bit: Size := SizeOf(TRGBQuad);
else
// if the image is not 24-bit or 32-bit go away
begin
ShowMessage('Your bitmap has unsupported color depth!');
Exit;
end;
end;

// iterate through the image vertically
for Y := 0 to (ABitmap.Height - 1) do
begin
// access the line of pixels and get the pointer to the first pixel of
// that line
Pixels := ABitmap.ScanLine[Y];
// iterate through the scanned line pixels horizontally
// for 24-bit images the pixels are stored like
// B -> G -> R -> B -> G -> R etc.
// for 32-bit images the pixels are stored like
// B -> G -> R -> A -> B -> G -> R -> A etc.
// so we can simply use e.g. byte array and iterate through
// it, if we have 24-bit image, we have to read each element,
// if 32-bit we have to skip the alpha (reserved) channel
for X := 0 to (ABitmap.Width - 1) do
begin
// store the pixel's red channel value
Red := Pixels^[(X * Size) + 2];
// modify the pixel's red channel value
Pixels^[(X * Size) + 2] := Pixels^[(X * Size)];
// modify the pixel's blue channel value
Pixels^[(X * Size)] := Red;
end;
end;
end;

关于delphi - 使用 ScanLine 快速交换红/蓝字节的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8931784/

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