DelphiでTPngImageを使った透過PNG画像の拡大・縮小と圧縮|アルファチャンネル対応のサンプルコード
DelphiのTPngImageを使って、透過PNG画像(アルファチャンネル付き・ビット透過・非透過)を拡大・縮小する方法を紹介します。
TransparencyModeの違いに応じて処理を分岐し、アルファ値を保持したままサイズ変更を行うサンプルコードを掲載。
圧縮レベル9などで保存することで、ファイルサイズの最適化も可能です。BMP画像の透過変換や、PNG画像のサンプル生成にも応用できます。
PNG画像には大きく以下3種類があるようです。
- 非透過性
- TPngImageのTransparencyModeプロパティが「ptmNone」の場合
- ビット透過性
-
TPngImageのTransparencyModeプロパティが「ptmBit」の場合
Transparentプロパティが「True」でTransparentColorプロパティに透過色が設定されています - アルファチャネル付き透過性
-
TPngImageのTransparencyModeプロパティが「ptmPartial」の場合
AlphaScanlineプロパティにアルファ値が入っています
拡大縮小プロシージャ
CreateResizePngFile(元のPNG画像ファイル名, 作成するPNG画像ファイル名, 拡大率);
のように使用します。
アルゴリズムは近接近傍法(ニアレストネイバー)です。
uses Imaging.pngimage;
procedure CreateResizePngFile(FromFile,ToFile:String;Rate:single=1);
Type
TRGB=record B,G,R:Byte; end;
TRGBArr=array[0..30000] of TRGB;
PRGBArr=^TRGBArr;
TRGBArrArr=array[0..30000] of PRGBArr;
TAlphaArrArr=array[0..30000] of pByteArray;
var PngF,PngT:TPngImage;
Bmp:TBitmap;
x,y:Integer;
RGBf,RGBt:TRGBArrArr;
Alphaf,Alphat:TAlphaArrArr;
begin
PngF := TPngImage.Create;
PngT := TPngImage.Create;
try
PngF.LoadFromFile(FromFile);
PngT.Assign(PngF);
PngT.SetSize(Trunc(PngF.Width*Rate),Trunc(PngF.Height*Rate));
if PngF.TransparencyMode=ptmPartial then
begin
//アルファチャネル付きのPNGファイルの場合
for y := 0 to PngF.Height-1 do
begin
RGBf[y]:=PngF.Scanline[y];
Alphaf[y]:=PngF.AlphaScanline[y];
end;
for y := 0 to PngT.Height-1 do
begin
RGBt[y]:=PngT.Scanline[y];
Alphat[y]:=PngT.AlphaScanline[y];
end;
for y := 0 to PngT.Height-1 do
begin
for x := 0 to PngT.Width-1 do
begin
RGBt[y][x].R:=RGBf[Trunc(y/Rate)][Trunc(x/Rate)].R;
RGBt[y][x].G:=RGBf[Trunc(y/Rate)][Trunc(x/Rate)].G;
RGBt[y][x].B:=RGBf[Trunc(y/Rate)][Trunc(x/Rate)].B;
Alphat[y][x]:=Alphaf[Trunc(y/Rate)][Trunc(x/Rate)];
end;
end;
end
else
begin
//PngF.TransparencyMode=ptmBit(ビット透過サポート) 又は
//PngF.TransparencyMode=ptmNone(非透過サポート) の場合
Bmp:=TBitmap.Create;
try
Bmp.SetSize(Trunc(PngF.Width*Rate),Trunc(PngF.Height*Rate));
Bmp.Canvas.Brush.Color:=PngF.TransparentColor;
Bmp.Canvas.FillRect(Bmp.Canvas.ClipRect);
Bmp.Canvas.StretchDraw(Bmp.Canvas.ClipRect,PngF);
PngT.Assign(Bmp);
PngT.Transparent:=PngF.Transparent;
PngT.TransparentColor:=PngF.TransparentColor;
finally
Bmp.Free;
end;
end;
Pngt.CompressionLevel:=9;//圧縮レベル(0~9)
PngT.SaveToFile(ToFile);
finally
PngF.Free;
PngT.Free;
end;
end;
使用例
procedure TForm1.Button1Click(Sender: TObject);
begin
CreateResizePngFile(
'..\..\アルファチャネル付き.png',
'..\..\アルファチャネル付きサイズ変更後.png',
2.5
);
CreateResizePngFile(
'..\..\ビット透過型.png',
'..\..\ビット透過型サイズ変更後.png',
0.8
);
CreateResizePngFile(
'..\..\非透過.png',
'..\..\非透過サイズ変更後.png',
1.5
);
end;
