TListViewとTImageListを組み合わせて、画像リストを表示させています。
画像のリストを選択状態にしたとき、画像の透明色部分がカーソルの色になるようにマスクしているのですが
gif、pngファイルから透明色を取得出来ません。
左上のピクセルを透明色として設定する場合は動作しますが
四隅が画像で中央が透明というのもあるので
透明色が取得出来ればと思うのですがうまくいきません。
どのようにすれば取得できるのでしょうか?
透明色の設定方法を参考にしています。
https://fishers.mydns.jp/pc/delphi/transgif.html
ファイルを読み込んだ後の gif.Images[0].ColorMap.Count の値は 0になっています。
Windows10 コンパイル環境はDelphiXE5です。
透明の画像データは、何種類かのアプリで作成しています。
アプリで読み込むときは透明色として読み込めています。
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls, Vcl.ExtCtrls;
type
TFormMain = class(TForm)
ListView1: TListView;
ImageList1: TImageList;
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
FormMain: TFormMain;
implementation
uses PNGImage,GIFImg;
{$R *.dfm}
procedure TFormMain.FormShow(Sender: TObject);
var
item : TListItem;
bmp : TBitmap;
mask : TBitmap;
png : TPngImage;
gif : TGIFImage;
GCE : TGIFGraphicControlExtension;
r : TRect;
begin
ImageList1.Height := 64;
ImageList1.Width := 64;
r := Rect(0,0,64,64);
bmp := TBitmap.Create;
mask := TBitmap.Create;
gif := TGIFImage.Create;
try
bmp.SetSize(64,64);
gif.LoadFromFile('imagetest.gif');
GCE := TGIFGraphicControlExtension.Create(gif.Images[0]);
bmp.Canvas.StretchDraw(r,gif);
mask.Assign(bmp);
mask.Mask(GCE.TransparentColor);
ImageList1.Add(bmp,mask);
finally
gif.Free;
mask.Free;
bmp.Free;
end;
r := Rect(0,0,64,64);
bmp := TBitmap.Create;
png := TPngImage.Create;
mask := TBitmap.Create;
try
bmp.SetSize(64,64);
png.LoadFromFile('imagetest.png');
bmp.Canvas.StretchDraw(r,png);
mask.Assign(bmp);
mask.Mask(png.TransparentColor);
ImageList1.Add(bmp,mask);
finally
mask.free;
png.Free;
bmp.Free;
end;
ListView1.LargeImages := ImageList1;
ListView1.SmallImages := ImageList1;
ListView1.ViewStyle := vsList;
item := ListView1.Items.Add;
item.Caption := 'gif';
item.ImageIndex := 0;
item := ListView1.Items.Add;
item.Caption := 'img';
item.ImageIndex := 1;
end;
var
PNG: TPNGImage;
MSK: TBitmap;
begin
MSK := TBitmap.Create;
PNG := TPNGImage.Create;
PNG.LoadFromFile('83232_sample.png');
MSK.Assign(PNG);
Image4.Picture.Bitmap.SetSize(200,200);
Image4.Picture.Bitmap.Canvas.Brush.Color := clRed;
Image4.Picture.Bitmap.Canvas.FillRect(Rect(0,0,200,200));
Image4.Picture.Bitmap.Mask(clRed);
Image4.Picture.Bitmap.Canvas.StretchDraw(Rect(0,0,200,200),PNG);
PNG.Free;
MSK.Free;
Exit;
透明部分は描画されないので TransparentColor でMask はできない
AAAAAさん、ありがとうございます。
pngの処理を下記のようにすることで希望通りの動作になりました。
疑問なのが画像ファイルで clRed 赤 RBG(255,0,0)を使っていても
その部分は透明にはならず描画されます。
理想の動作ですが画像によっては意図しないところが透明になったりするのでしょうか?
r := Rect(0,0,64,64);
bmp := TBitmap.Create;
png := TPngImage.Create;
mask := TBitmap.Create;
try
bmp.SetSize(64,64);
png.LoadFromFile('imagetest.png');
bmp.Canvas.Brush.Color := clRed;
bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
bmp.Canvas.StretchDraw(r,png);
mask.Assign(bmp);
mask.Mask(clRed);
ImageList1.Add(bmp,mask);
finally
mask.free;
png.Free;
bmp.Free;
end;
AAAAAさん、ありがとうございました。
今まで苦労していたのがウソのようです。
StretchDrawを使うと赤の部分が若干残ったので
使用する色は、その時の背景色とすることで解決しました。
問題に対する解決策ということではありませんが.
( GIF ファイルではなく ) GIF 画像の透過色を取得して,
ビットマップのマスク画像を作成する作成する例です.
LBitmapMask が TImageList.Add の第 2 引数に渡す値です.
取得するのは透明色ではなく,透過色です.
R, G, B, A の値が全て 0 が「透明色」です.
PNG 画像の透明色のピクセルは,透過状態となります.
procedure TForm1.Button1Click(Sender: TObject);
var
LBitmap : TBitmap;
LBitmapMask : TBitmap;
LGifImg : TGIFImage;
begin
LBitmap := TBitmap.Create;
LBitmapMask := TBitmap.Create;
LGifImg := TGIFImage.Create;
try
LBitmap.SetSize(128, 128);
LGifImg.LoadFromFile('128X128_GIF_01.gif');
LGifImg.Transparent := False;
LBitmap.Canvas.Draw(0, 0, LGifImg);
LBitmapMask.Assign(LBitmap);
LBitmapMask.Mask(LGifImg.Bitmap.TransparentColor);
Image1.Canvas.Draw(0, 0, LBitmap);
Image2.Canvas.Draw(0, 0, LBitmapMask);
finally
FreeAndNil(LBitmap);
FreeAndNil(LBitmapMask);
FreeAndNil(LGifImg);
end;
end;
ツイート | ![]() |