delphi – 将ImgView32透明层保存到PNG
我在将ImgView32图层保存为TRANSPARENT PNG时遇到问题.
我使用 this question中的代码进行保存. 但是,图像以白色背景保存. 这是我如何初始化我的ImgView32,在其上创建一个图层,然后在其上绘制一条线: procedure TputLine.FormCreate(Sender: TObject); var P: TPoint; W,H: Single; imwidth: integer; imheight: integer; begin imwidth := Iv1.Width; imheight := Iv1.Height; with iv1 do begin Selection := nil; Layers.Clear; Scale := 1; Scaled := True; Bitmap.DrawMode := dmTransparent; Bitmap.SetSize(imwidth,imheight); Bitmap.Canvas.Pen.Width := 4; end; BL := TBitmapLayer.Create(iv1.Layers); try BL.Bitmap.DrawMode := dmTransparent; BL.Bitmap.SetSize(imwidth,imheight); BL.Bitmap.Canvas.Pen.Width := penwidth; BL.Bitmap.Canvas.Pen.Color := pencolor; BL.Location := GR32.FloatRect(0,imwidth,imheight); BL.Scaled := False; except BL.Free; raise; end; end; 所以iv1是我的ImgView32的名称. var bm32:TBitmapLayer; ... begin bm32:=(iv1.Layers[0] as TBitmapLayer).Bitmap; bm32.canvas.pen.color:=clwhite; bm32.canvas.brush.color:=clwhite; bm32.canvas.rectangle(0,bm32.width-1,bm32.height-1); bm32.canvas.Pen.Color:=WinColor(ColorPickerGTK1.SelectedColor); bm32.canvas.brush.color:=clWhite; bm32.Canvas.Pen.Width:=3; bm32.Canvas.MoveTo(0,bm32.Height); bm32.Canvas.LineTo(0+150,bm32.Height-250); end; 如果我在绘制矩形时使用clWhite32作为上面的代码,那么在保存PNG时,imgView的背景会变黑……所以我真的不明白这个问题. 我像这样保存: procedure TputLine.Button2Click(Sender: TObject); var myLay:TBitmapLayer; begin mylay := iv1.Layers.Items[0] as TBitmapLayer; SavePNGTransparentX(mylay.Bitmap); end; 和实际的保存代码(来自上述链接) procedure TPutLine.SavePNGTransparentX(bm32:TBitmap32); var Y: Integer; X: Integer; Png: TPortableNetworkGraphic32; function IsWhite(Color32: TColor32): Boolean; begin Result:= (TColor32Entry(Color32).B = 255) and (TColor32Entry(Color32).G = 255) and (TColor32Entry(Color32).R = 255); end; begin bm32.ResetAlpha; for Y := 0 to bm32.Height-1 do for X := 0 to bm32.Width-1 do begin if IsWhite(bm32.Pixel[X,Y]) then bm32.Pixel[X,Y]:=Color32(255,255,0); end; Png:= TPortableNetworkGraphic32.Create; Png.Assign(bm32); Png.SaveToFile('C:ThisShouldBeTransparent.png'); Png.Free; end; 我不明白为什么它不将图层保存为透明PNG. 您可以使用上面的代码复制我的问题.它使用GR32_PNG和GR32_PortableNetworkGraphic.您只需要在表单中添加TImgView32控件并添加上面列出的代码. 解决方法
问题的原因似乎是双重的.
>首先,当你打电话给Png.Assign(bm32);在单元格GR32_PNG中,它试图找出存储图像的最小格式.如果图像的颜色少于256种,则会创建一个调色板格式,并根据找到的颜色数量,位深度可以变为1,2,4或8.据我所知,只有具有TrueColor和Alpha的图像可以保存为可变透明度png图像. TPortableNetworkGraphic32类有两个属性,BitDepth和ColorType控制png图像的格式,如果它们是可设置的,这将是有用的!试图在代码中将它们设置为: Png.BitDepth := 8; Png.ColorType := ctTrueColorAlpha; 导致例外
从措辞上我们可以假设将来会有一些进一步的发展. 治愈 要绕过上述图像分析,您可以更改GR32_PNG.pas中的第459行. procedure TPortableNetworkGraphic32.AssignPropertiesFromBitmap32() var ... begin ... IsPalette := True; // <--- change to False ... 如果少于256种颜色,那将处理位深度分析并防止调色板创建. 然后,对于SavePNGTransparentX()过程,您可能感兴趣的更改一次.如您所见,它需要绘图表面的背景为白色,因为它专门为所有白色像素将Alpha通道设置为零.然而,TBitmapLayer被初始化为所有像素(RGBA)为全零,因此每个像素的颜色分量构成黑色(由于alpha通道为零,因此不可见).因此,您需要使用白色填充绘图图层,这会使其变得不透明,这会再次覆盖所有较低的图层(在绘图图层下方). 要对此进行更正,您可以 >将绘图层的初始化删除为全白 代码将成为 procedure TForm8.SavePNGTransparentX(bm32:TBitmap32); var Y: Integer; X: Integer; Png: TPortableNetworkGraphic32; function IsBlack(Color32: TColor32): Boolean; begin Result:= (TColor32Entry(Color32).B = 0) and (TColor32Entry(Color32).G = 0) and (TColor32Entry(Color32).R = 0); end; function IsWhite(Color32: TColor32): Boolean; begin Result:= (TColor32Entry(Color32).B = 255) and (TColor32Entry(Color32).G = 255) and (TColor32Entry(Color32).R = 255); end; begin bm32.ResetAlpha; for Y := 0 to bm32.Height-1 do for X := 0 to bm32.Width-1 do begin // if IsWhite(bm32.Pixel[X,Y]) then // bm32.Pixel[X,0); if IsBlack(bm32.Pixel[X,Y]:=Color32( 0,0); end; Png:= TPortableNetworkGraphic32.Create; Png.Assign(bm32); Png.SaveToFile('C:tmpimgsThisShouldBeTransparent3.png'); Png.Free; end; 通过此更改,您可以看到绘图图层下方的图层,并且绘图图层的结果文件将使所有未绘制的像素都透明. 这是一些图像,首先是在底层加载位图的ImageView: 然后,我在BL层上绘制一个蓝色十字(参考你的代码)基本上使用Button1Click()中的代码,但没有白色矩形. 然后我将BL图层保存为.png文件并使用Windows资源管理器“预览”查看它: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |