我使用德尔福XE2中Gustavo Daud版本1.4的TPNGList如何在Delphi中将PNG图像的颜色从白色更改为黑色?
它使用一些PNG 256x256图像作为按钮图像。
但是有必要改变背景颜色和图像的对比度不好。
所以我现在有黑色背景的白色图像。
我需要将它们更改为浅色背景。
有透明度,应保存。只有白色像素。但是,目标函数的一个通用源也是很棒的。
编辑: 继sugestion为“去了”我曾尝试以下,但只得到黑色或白色盒子:
procedure PNGInvertWB(Image: TPngImage; AWhite: Boolean);
procedure WBInvertRGB(var R, G, B: Byte);
var
color: LongInt;
begin
if AWhite then
begin
if RGB(R, G, B) = clWhite then
begin
Color := ColorToRGB(clBlack);
R := GetRValue(Color);
G := GetGValue(Color);
B := GetBValue(Color);
end;
end
else
begin
if RGB(R, G, B) = clBlack then
begin
Color := ColorToRGB(clWhite);
R := GetRValue(Color);
G := GetGValue(Color);
B := GetBValue(Color);
end;
end;
end;
var
X, Y, PalCount: Integer;
Line: PRGBLine;
PaletteHandle: HPalette;
Palette: array[Byte] of TPaletteEntry;
begin
if not (Image.Header.ColorType in [COLOR_GRAYSCALE, COLOR_GRAYSCALEALPHA]) then begin
if Image.Header.ColorType = COLOR_PALETTE then begin
PaletteHandle := Image.Palette;
PalCount := GetPaletteEntries(PaletteHandle, 0, 256, Palette);
for X := 0 to PalCount - 1 do
WBInvertRGB(Palette[X].peRed, Palette[X].peGreen, Palette[X].peBlue);
SetPaletteEntries(PaletteHandle, 0, PalCount, Palette);
Image.Palette := PaletteHandle;
end
else begin
for Y := 0 to Image.Height - 1 do begin
Line := Image.Scanline[Y];
for X := 0 to Image.Width - 1 do
WBInvertRGB(Line[X].rgbtRed, Line[X].rgbtGreen, Line[X].rgbtBlue);
end;
end;
end;
end;
我打电话这个使用此代码:
procedure TDBNavigator.UpdateColor;
var
PNGImage: TPngImage;
HCColor : TColor;
procedure Invert(AImage: TImage; AWhite: boolean);
begin
ConvertToPNG(AImage.Picture.Graphic, PNGImage);
PNGInvertWB(PNGImage, not AWhite);
AImage.Picture.Graphic := PNGImage;
end;
begin
Color := ThemeManager.CurrentPallete.Color[FThemeColor];
HCColor := ThemeManager.CurrentPallete.HighContrast(FThemeColor);
if HCColor <> FCurrentColor then
begin
Invert(uiPrevious, HCColor = clWhite);
Invert(uiNext, HCColor = clWhite);
Invert(uiInsert, HCColor = clWhite);
Invert(uiPost, HCColor = clWhite);
Invert(uiCancel, HCColor = clWhite);
Invert(uiDelete, HCColor = clWhite);
Invert(uiRefresh, HCColor = clWhite);
FCurrentColor := HCColor;
end;
end;
不确定哪部分是错误的。这是一个组件的一部分,我试图改变设计时分配的图像。这是我加载的PNG图像,256x256具有透明度。
我需要使用TImage,我知道它不是一个按钮。并且可能有组件会这样做。我需要自己制作,因为我正在使用特定的库。
我得到了PNGInvertWB想法从PNGFunctions的古斯塔沃功能之一:
procedure MakeImageGrayscale(Image: TPngImage; Amount: Byte = 255);
所以,我必须与所有图像没有经验,什么是错的代码?
这是怎么看起来像在组件上,我有自己的设计:
原文:
后:
我用下面的函数从PNGFunctions尝试这个:
procedure MakeImageGrayscale(Image: TPngImage; Amount: Byte = 255);
procedure GrayscaleRGB(var R, G, B: Byte);
var
X: Byte;
begin
X := Round(R * 0.30 + G * 0.59 + B * 0.11);
R := Round(R/256 * (256 - Amount - 1)) + Round(X/256 * (Amount + 1));
G := Round(G/256 * (256 - Amount - 1)) + Round(X/256 * (Amount + 1));
B := Round(B/256 * (256 - Amount - 1)) + Round(X/256 * (Amount + 1));
end;
var
X, Y, PalCount: Integer;
Line: PRGBLine;
PaletteHandle: HPalette;
Palette: array[Byte] of TPaletteEntry;
begin
//Don't do anything if the image is already a grayscaled one
if not (Image.Header.ColorType in [COLOR_GRAYSCALE, COLOR_GRAYSCALEALPHA]) then begin
if Image.Header.ColorType = COLOR_PALETTE then begin
//Grayscale every palette entry
PaletteHandle := Image.Palette;
PalCount := GetPaletteEntries(PaletteHandle, 0, 256, Palette);
for X := 0 to PalCount - 1 do
GrayscaleRGB(Palette[X].peRed, Palette[X].peGreen, Palette[X].peBlue);
SetPaletteEntries(PaletteHandle, 0, PalCount, Palette);
Image.Palette := PaletteHandle;
end
else begin
//Grayscale every pixel
for Y := 0 to Image.Height - 1 do begin
Line := Image.Scanline[Y];
for X := 0 to Image.Width - 1 do
GrayscaleRGB(Line[X].rgbtRed, Line[X].rgbtGreen, Line[X].rgbtBlue);
end;
end;
end;
end;
我在哪里改变了e GrayscaleRGB,因为它获取每个像素并将其更改为灰度,因此我相信我可以相应地变为黑色或白色。
我会保留一对外部准备/修改的图像集。如果涉及部分透明度,则反锯齿(局部)部分在非预期的颜色值背景上看起来很糟糕。 –