图像透明度

时间:2011-09-11 10:29:08

标签: image delphi transparency

通常我允许我的用户在主窗体中放置图像。

因为有些图像会产生很大的噪音,所以我想稍微平滑一下。

我通常在默认情况下提供的图像中有一些透明度。

当用户选择新图像或加载图像时,如何自动执行此操作?

2 个答案:

答案 0 :(得分:5)

将跟踪栏添加到TOpenPictureDialog衍生设置透明度级别:

unit OpenFadedPictureDialog;

interface

uses
  Classes, Controls, ExtDlgs, ComCtrls, StdCtrls, Windows, Graphics, ExtCtrls;

type
  TOpenFadedPictureDialog = class(TOpenPictureDialog)
  private
    FFader: TTrackBar;
    FFaderLabel: TLabel;
    FBlendFunc: BLENDFUNCTION;
    FTimer: TTimer;
    procedure Delayed(Sender: TObject);
    procedure FaderChanged(Sender: TObject);
    procedure UpdateImage;
  protected
    procedure DoShow; override;
    procedure DoSelectionChange; override;
  public
    constructor Create(AOwner: TComponent); override;
    function Picture: TPicture;
    function TransparancyLevel: Byte;
  end;

implementation

{ TOpenFadedPictureDialog }

resourcestring
  SFaderHint = 'Track bar to set image transparancy.';
  SFaderLabelCaption = 'Image transparancy:';

constructor TOpenFadedPictureDialog.Create(AOwner: TComponent);
begin
  inherited Create(Owner);
  FFaderLabel := TLabel.Create(Self);
  FFaderLabel.Name := 'FaderLabel';
  FFaderLabel.Align := alTop;
  FFaderLabel.Caption := SFaderLabelCaption;
  FFader := TTrackBar.Create(Self);
  FFader.Name := 'FaderTrackBar';
  FFader.Align := alTop;
  FFader.Height := 25;
  FFader.TickStyle := tsNone;
  FFader.PageSize := 25;
  FFader.Max := 255;
  FFader.Position := 127;
  FFader.Hint := SFaderHint;
  FFader.OnChange := FaderChanged;
  FBlendFunc.BlendOp := AC_SRC_OVER;
  FBlendFunc.SourceConstantAlpha := 127;
  FTimer := TTimer.Create(Self);
  FTimer.Enabled := False;
  FTimer.Interval := 100;
  FTimer.OnTimer := Delayed;
end;

procedure TOpenFadedPictureDialog.Delayed(Sender: TObject);
begin
  FTimer.Enabled := False;
  FBlendFunc.SourceConstantAlpha := FFader.Position;
  if (ImageCtrl.Picture <> nil) and (ImageCtrl.Picture.Graphic <> nil) then
    ImageCtrl.Picture.LoadFromFile(FileName);
  UpdateImage;
end;

procedure TOpenFadedPictureDialog.DoSelectionChange;
begin
  inherited DoSelectionChange;
  UpdateImage;
end;

procedure TOpenFadedPictureDialog.DoShow;
begin
  with ImageCtrl do
  begin
    Picture := nil;
    Align := alTop;
    Anchors := [akLeft, akTop, akRight, akBottom];
    Height := Height - FFaderLabel.Height + FFader.Height - 15;
    FFaderLabel.Parent := Parent;
    FFader.Parent := Parent;
  end;
  inherited DoShow;
end;

procedure TOpenFadedPictureDialog.FaderChanged(Sender: TObject);
begin
  FTimer.Enabled := False;
  FTimer.Enabled := True;
end;

function TOpenFadedPictureDialog.Picture: TPicture;
begin
  Result := ImageCtrl.Picture;
end;

function TOpenFadedPictureDialog.TransparancyLevel: Byte;
begin
  Result := FBlendFunc.SourceConstantAlpha;
end;

procedure TOpenFadedPictureDialog.UpdateImage;
var
  Src: TBitmap;
  Dst: TBitmap;
begin
  if (ImageCtrl.Picture <> nil) and (ImageCtrl.Picture.Graphic <> nil) then
  begin
    Src := TBitmap.Create;
    Dst := TBitmap.Create;
    try
      Src.Width := ImageCtrl.Picture.Width;
      Src.Height := ImageCtrl.Picture.Height;
      Dst.Width := Src.Width;
      Dst.Height := Src.Height;
      Src.Canvas.Draw(0, 0, ImageCtrl.Picture.Graphic);
      AlphaBlend(Dst.Canvas.Handle, 0, 0, Dst.Width, Dst.Height,
        Src.Canvas.Handle, 0, 0, Src.Width, Src.Height, FBlendFunc);
      ImageCtrl.Picture.Graphic := Dst;
    finally
      Dst.Free;
      Src.Free;
    end;
  end;
end;

end.

创建此对话框以在使用TransparancyLevel功能执行后获取用户所需的透明度级别,或将所选图片分配给主表单上的图像:

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TOpenFadedPictureDialog.Create(nil) do
    try
      if Execute then
        Image1.Picture := Picture;
    finally
      Free;
    end;
end;

自定义常用对话框的示例图片:

Customized common dialog

答案 1 :(得分:1)

我在Delphi中做了很长时间(自从我使用Delphi已经很久了!!)但是如果内存对我有用,delphi中的所有TBitmap和TImage类型都使用图像中的左上角像素知道透明度的关键是什么。

基本上,您会找到背景颜色(通常是邻近的,如果不是相同的像素),请确保左上角的像素是该颜色,然后将图像透明度键设置为该像素的RGB值。

就像我说它已经有一段时间了,你可能需要对这些细节进行一些挖掘,但我很确定它是类似的。