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:
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.
精彩评论