Прозрачность изображения - PullRequest
       10

Прозрачность изображения

1 голос
/ 11 сентября 2011

Обычно я разрешаю пользователям размещать изображение в основной форме.

Поскольку некоторые изображения вызывают сильный шум, я бы хотел сгладить их немного.

Обычно я делаю некоторыепрозрачность в изображениях, которые я задаю по умолчанию.

Как я могу сделать это автоматически, когда пользователь выбирает новое изображение или когда я его загружаю?

Ответы [ 2 ]

5 голосов
/ 11 сентября 2011

Добавить трекбар к производной 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 голос
/ 11 сентября 2011

Прошло много времени с тех пор, как я делал это в Delphi (прошло много времени с тех пор, как я использовал Delphi !!), однако, если память мне не изменяет, все типы TBitmap и TImage в Delphi используют самый верхний левый пиксель изображения, чтобы знать, что такое ключ прозрачности.

Как правило, вы находите цвет фона (обычно смежный, если уже не тот же пиксель), убедитесь, что верхний левый пиксель соответствует этому цвету, а затем установите для ключа прозрачности изображения значение RGB этого пикселя.

Как я уже говорил, вам, возможно, придется немного покопаться в этих деталях, но я уверен, что это что-то похожее.

...