2

TImage を含む透明なフォームを持つ小さな EXE を作成しました。フォームを透明にするために、次のコードを使用します。

Function TForm1.CombineRegions (FrmX , FrmY  :Integer;CtrlComp : TControl;Var RegHandle : THandle) : Boolean;

Var
CtrlHandle : THandle;
 CtrlLeft,
 CtrlTop,
 CtrlWidth,
 CtrlHt     : Integer;
begin
  Result := False;
  CtrlHandle := 0;
  FrmX := 0;
  FrmY := 0;
  Try
      CtrlLeft   := CtrlComp.Left;
      CtrlTop    := CtrlComp.Top;
      CtrlWidth  := CtrlComp.Width;
      CtrlHt     := CtrlComp.Height;

 Except
     Exit;
 End;

 Try
   FrmX:=0;
   FrmY:=0;
   FrmX := FrmX + CtrlLeft;
   FrmY := FrmY + CtrlTop;
   CtrlHandle := CreateRectRgn(FrmX, FrmY, FrmX + CtrlWidth, FrmY + CtrlHt) ;
   CombineRgn(RegHandle, RegHandle, CtrlHandle, RGN_OR) ;
Except
End;
End;

それが行うことは、最初にすべてのフォームを非表示にすることです。次に、フォームに必要なコントロールに従って、上記の関数を呼び出し、その領域のみが描画されます。これで、私の TImage に背景色のある画像ができました。画像

ご覧のとおり、画像には背景があります。領域全体ではなく、内部のビットマップのみが描画されるように、TImage を描画したいと考えています。それはできますか?前もって感謝します。

4

2 に答える 2

0

画面にブレンドされた 32 ビット PNG 画像のみを表示するスプラッシュ フォームがあります。

unit SplashU;

interface

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

type
  TSplashForm = class(TForm)
    SplashImg: TImage;
  public
    procedure Execute;
  end;

var
  SplashForm: TSplashForm;

implementation

{$R *.dfm}

procedure TSplashForm.Execute;
var
  t: Cardinal;
  f: TBlendFunction;
  p: TPoint;
  z: TSize;
  s: DWORD;
  b: TBitmap;
  x, y:integer;
  a, d,c: PByteArray;
begin
s := GetWindowLongA(Handle, GWL_EXSTYLE);
if (s and WS_EX_LAYERED = 0) then
  SetWindowLong(Handle, GWL_EXSTYLE, s or WS_EX_LAYERED);

b := TBitmap.Create;
b.Width :=  SplashImg.Width;
b.Height :=  SplashImg.Height;
b.PixelFormat := pf32bit;
for y := SplashImg.Height - 1 downto 0 do
  begin
  a := (SplashImg.Picture.Graphic as TPNGObject).AlphaScanline[y];
  c := (SplashImg.Picture.Graphic as TPNGObject).Scanline[y];
  d := b.ScanLine[y];
  for x := 0 to SplashImg.Width - 1 do
    begin
    d^[x * 4 + 3] := a^[x];
    d^[x * 4] := MulDiv(c^[x * 3], a^[x], 255);
    d^[x * 4 + 1] := MulDiv(c^[x * 3 + 1], a^[x], 255);
    d^[x * 4 + 2] := MulDiv(c^[x * 3 + 2], a^[x], 255);
    end;
  end;

p := Point(0, 0);
z.cx := b.Width;
z.cy := b.Height;

f.BlendOp := AC_SRC_OVER;
f.BlendFlags := 0;
f.SourceConstantAlpha := 0;
f.AlphaFormat := AC_SRC_ALPHA;

Show;
t := 0;
while (f.SourceConstantAlpha < 255) do
  begin
  while (t = GetTickCount) do Sleep(25);
  t := GetTickCount;
  Inc(f.SourceConstantAlpha, (255 - f.SourceConstantAlpha) div 32 + 1);
  UpdateLayeredWindow(Handle, 0, nil, @z, b.Canvas.Handle, @p, 0, @f, ULW_ALPHA);
  end;
b.Free;
end;

end.
于 2012-08-08T10:41:53.577 に答える
0

通常のフォームを取得し、そのすべてのエッジ/キャプションを非表示にします。そのフォームに画像を配置し、alClient に合わせます。for ループでフォームの透明度 (TForm.AlphaBlendValue) を 0 から 255 に設定します。

擬似コード:

procedure ShowSplashScreen;
begin
 frmSplash:= TfrmSplash.Create(NIL);
 frmSplash.imgSplash.Picture.LoadFromFile('Splash.png');
 frmSplash.AlphaBlendValue:= StartValue; // This is about 50
 frmSplash.CurrAlpha:= frmSplash.AlphaBlendValue;
 frmSplash.Increment:= 5;  
 frmSplash.Show;         
 frmSplash.FormStyle := fsStayOnTop;   
 frmSplash.Timer.Enabled:= TRUE;
end;

PNG画像(透明度あり)で使用すると機能します。

于 2022-01-04T20:20:39.643 に答える