【问题标题】:Draw Transparent Scaled PNG绘制透明缩放 PNG
【发布时间】:2015-12-29 03:52:55
【问题描述】:

我有一个大的 (300x300px) PNG 图像,我需要重新缩放。在另一个SO question 中,我读到了StretchBltHALFTONE,以便更好地扩展。

我的问题是如何绘制透明的 PNG 图像,或者至少将黑角涂成白色?

正如您在附图中看到的那样,我得到了黑角。

这是原始图像: 这是我到目前为止所尝试的。

unit MainU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TFormMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}
uses
  Pngimage;

type
  TIRButton = class(TImage)
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TGraphicControlAcess = class(TGraphicControl);
  TGraphicAcess = class(TGraphic);

  THalfTonePngImage = class(TPngImage)
  protected
    procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
  end;

  { TIRButton }

constructor TIRButton.Create(AOwner: TComponent);
begin
  inherited;
  Center := True;
  Proportional := True;
end;

procedure TIRButton.Paint;
var
  ParentCanvas: TCanvas;
begin
  ParentCanvas := TGraphicControlAcess(Self).Canvas;
  TGraphicAcess(Picture.Graphic).Draw(ParentCanvas, DestRect);
end;

{ THalfTonePngImage }

procedure THalfTonePngImage.Draw(ACanvas: TCanvas; const Rect: TRect);
var
  p: TPoint;
  dc: HDC;
begin
  dc := ACanvas.Handle;
  GetBrushOrgEx(dc, p);
  SetStretchBltMode(dc, HALFTONE);
  SetBrushOrgEx(dc, p.X, p.Y, @p);

  ACanvas.Brush.Color := clWhite;
  ACanvas.FillRect(Classes.Rect(0, 0, Width, Height));

  StretchBlt(
    dc, 0, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top,
    Canvas.Handle, 0, 0, Width, Height, ACanvas.CopyMode
    );
end;

procedure TFormMain.FormCreate(Sender: TObject);
var
  Image: THalfTonePngImage;
begin
  Image := THalfTonePngImage.Create;
  Image.LoadFromFile('X200IR_11_EmgBrake.png');

  with TIRButton.Create(Self) do
  begin
    Width := 100;
    Height := 100;
    Picture.Assign(Image);
    Parent := Self;
    Anchors := [akLeft, akTop, akRight, akBottom];
  end;

  Image.Free;
end;

end.

【问题讨论】:

  • 您希望整个图像是透明的,还是“不画角”?后者将是一个问题,因为它们是黑色的,我想虽然“绘制 everything that is black in white”会做到这一点,但不是您正在寻找的解决方案。你需要一个覆盖角落的面具。确实,摆脱角落的最简单方法是在图像编辑器中打开图像。
  • 最好我希望边角是透明的,如果这很难做到,那么边角是白色的。
  • 图片是你现在得到的截图。你也可以显示原始图像吗?如果无法编辑原图,能否用另一张图作为蒙版?
  • 截屏是我今天得到的。是的,我可以使用其他图像作为蒙版。我将添加原始图像。
  • 首先我建议你从TGraphicControl(不是TImage)派生TIRButton,它已经暴露了Canvas并且适合这种控制。其次,我认为TPngImage应该支持通过.Draw(ACanvas: TCanvas; const Rect: TRect)设计绘制缩放透明PNG。至少“老”TPngObject 支持它...

标签: delphi winapi png delphi-xe image-scaling


【解决方案1】:

源图像的角是透明的。由于白色背景,它在正确的图像中不可见。 StretchBlt 不支持透明度。因为它没有,透明像素与黑色无法区分。 (如果 ARGB 颜色为 FF 00 00 00,并且我们移除了 Alpha 通道,则剩下 00 00 00

您需要使用TransparentBlt

作为参考,这是放置在绿色背景上的图像。这样更容易看到透明度。

【讨论】:

    猜你喜欢
    • 2010-10-08
    • 1970-01-01
    • 2012-04-19
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多