我在窗体上放置了一个TImage并在其中设置了PNG图像。
是否可以在运行时更改PNG图像每个像素的不透明度?我想根据应用程序中的特定操作更改不透明度。
我正在使用以下代码使像素变暗,其想法是将该功能应用于TImage中的每个像素:
function DarkerColor(thisColor: TColor; thePercent: Byte): TColor;
var
(* a TColor is made out of Red, Green and blue *)
cRed,
cGreen,
cBlue: Byte;
begin
(* get them individually *)
cRed := GetRValue(thisColor);
cGreen := GetGValue(thisColor);
cBlue := GetBValue(thisColor);
(* make them darker thePercent *)
(* we need a byte value but the "/" operator
returns a float value so we use Round function
because type mismatch *)
cRed := Round(cRed * thePercent / 100);
cGreen := Round(cGreen * thePercent / 100);
cBlue := Round(cBlue * thePercent / 100);
(* return them as TColor *)
Result := RGB(cRed, cGreen, cBlue);
end;
我发现了如何访问BMP图像中的每个像素。事实是,我正在使用加载了PNG的TImage。
谢谢!
答案 0 :(得分:4)
只需使用ScanLine
图像中的PNG
使其变暗,然后再将其分配给TImage
组件。然后应该更快,然后将TBitmap
从TImage
转换为PNG
,执行操作并将其转换回TBitmap
,然后再次将其分配给TImage
组件。另外,将PNG
分配给TBitmap
后,将无法收回PNG
的部分透明度。至少,我过去的所有尝试都没有成功,这就是为什么我更喜欢将PNG
文件存储在我的小程序中并在运行期间更改(调整大小,混合等)其副本 -时间。
我更改了源代码,以排除带浮点的操作。它已被MulDiv
函数取代。
function DarkerColor(thisColor: TColor; thePercent: Byte): TColor;
var
(* a TColor is made out of Red, Green and blue *)
cRed,
cGreen,
cBlue: Byte;
begin
(* get them individually *)
cRed := GetRValue(thisColor);
cGreen := GetGValue(thisColor);
cBlue := GetBValue(thisColor);
(* make them darker thePercent *)
cRed := MulDiv(cRed, thePercent, 100);
cGreen := MulDiv(cGreen, thePercent, 100);
cBlue := MulDiv(cBlue, thePercent, 100);
(* return them as TColor *)
Result := RGB(cRed, cGreen, cBlue);
end;
现在,您可以进一步使用ScanLine
图像中的PNG
:
procedure MakePNGDarker(APNGInOut: TPNGImage; AValue: Integer);
type
TRGBArray = Array [0..65535 - 1] of WinAPI.Windows.tagRGBTRIPLE;
PRGBArray = ^TRGBArray;
var
RowInOut: PRGBArray;
SourceColor: TColor;
ResultColor: TColor;
X: Integer;
Y: Integer;
begin
if not Assigned(APNGInOut) or (AValue < 0) then
Exit;
for Y:=0 to APNGInOut.Height - 1 do
begin
RowInOut := APNGInOut.ScanLine[Y];
for X:=0 to APNGInOut.Width - 1 do
begin
SourceColor := RGB(RowInOut[X].rgbtRed, RowInOut[X].rgbtGreen, RowInOut[X].rgbtBlue);
ResultColor := DarkerColor(SourceColor, AValue);
RowInOut[X].rgbtRed := GetRValue(ResultColor);
RowInOut[X].rgbtGreen := GetGValue(ResultColor);
RowInOut[X].rgbtBlue := GetBValue(ResultColor);
end;
end;
end;
这是功能完成的工作的结果。
图A 代表原始图片; 从B到F的数字是的修改图像的灰度,其暗度设置为25到0到100。
注意
彩色图像的边缘模糊不清,因为这些图像的边缘模糊不清。这不是功能工作的结果!
有用的资源