开发者

Image transparency

开发者 https://www.devze.com 2023-04-04 05:56 出处:网络
Usually I allow my users to place an image in the main form. Because s开发者_如何转开发ome images cause to much noise, I would like to smooth those a bit.

Usually I allow my users to place an image in the main form.

Because s开发者_如何转开发ome images cause to much noise, I would like to smooth those a bit.

I usually do some transparency in the images that I give as defaults.

How can I do this automatically as the user selects a new image, or as I load it?


Add a trackbar to a TOpenPictureDialog derivative setting the transparancy level:

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.

Create this dialog to obtain the user's desired transparancy level after execution with the TransparancyLevel function, or assign the chosen picture to the image on your main form:

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

Example image of customized common dialog:

Image transparency


Been a long time since I did this in Delphi (It's been a long time since I used Delphi!!) however if memory serves me right, all TBitmap and TImage types in delphi use the top left most pixel in the image to know what the transparency key is.

Basically, you find the background colour (Usually adjacent if not already the same pixel) make sure the top left pixel is that colour, then set the images transparency key to the RGB value of that pixel.

Like I say it's been a while, you may have to dig a bit with those details, but I'm fairly sure it's something similar.

0

精彩评论

暂无评论...
验证码 换一张
取 消