Delphi XE2 で Gustavo Daud バージョン 1.4 の TPNGList を使用しています
ボタン画像として使用するPNG 256x256画像をいくつか保持しています。
ただし、背景色を変更する必要があり、画像のコントラストが良くありません。
だから私は今暗い背景のための白いイメージを持っています.
明るい背景用に黒に変更する必要があります。
透明性があり、維持する必要があります。白いピクセルしかありません。しかし、一般的なソースからターゲットへの関数も素晴らしいでしょう。
編集:「それを実行してください」の提案に従って、次のことを試しましたが、黒または白のボックスしか取得しません:
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;
どの部分が間違っているかわかりません。これは 1 つのコンポーネントの一部であり、設計時に割り当てられたイメージを変更しようとしています。私が読み込んだのは、透明度のある 256x256 の PNG 画像でした。
その TImage を使用する必要があります。ボタンではないことはわかっています。そして、おそらくそれを行うコンポーネントがあります。私が使用している特定のライブラリのため、自分で作成する必要があります。
PNGFunctions の Gustavo 関数の 1 つから PNGInvertWB のアイデアを得ました。
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;
各ピクセルを取得してグレースケールに変更していたため、GrayscaleRGB を変更したところ、それに応じて黒または白に変更できると信じていました。