Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Delphi中以alpha混合PNG形式淡入 几年前,当我第一次发布Vista的时候,我问了一个关于这个问题,但是从来没有解决这个问题,把它搁置起来作为以后要考虑的事情。p>_Delphi_Png_Alphablending - Fatal编程技术网

在Delphi中以alpha混合PNG形式淡入 几年前,当我第一次发布Vista的时候,我问了一个关于这个问题,但是从来没有解决这个问题,把它搁置起来作为以后要考虑的事情。p>

在Delphi中以alpha混合PNG形式淡入 几年前,当我第一次发布Vista的时候,我问了一个关于这个问题,但是从来没有解决这个问题,把它搁置起来作为以后要考虑的事情。p>,delphi,png,alphablending,Delphi,Png,Alphablending,我有一个闪屏,我花了很大的努力使它看起来很棒。这是一个32bpp的alpha混合PNG。我有一些代码(如果需要,我可以挖掘!),在Windows XP或Vista+下,当桌面合成关闭时,这些代码非常有效。然而,在Vista+下,所有的透明部分都是黑色的,破坏了它所有看起来很棒的东西 所以,我的问题是:任何人都能够将32bpp的alpha混合PNG显示为启动屏幕,无论是否激活桌面合成,都可以?我不反对使用第三方组件,如果需要,免费或其他 理想情况下,这将在Delphi7中工作 更新:除了下面的答案

我有一个闪屏,我花了很大的努力使它看起来很棒。这是一个32bpp的alpha混合PNG。我有一些代码(如果需要,我可以挖掘!),在Windows XP或Vista+下,当桌面合成关闭时,这些代码非常有效。然而,在Vista+下,所有的透明部分都是黑色的,破坏了它所有看起来很棒的东西

所以,我的问题是:任何人都能够将32bpp的alpha混合PNG显示为启动屏幕,无论是否激活桌面合成,都可以?我不反对使用第三方组件,如果需要,免费或其他

理想情况下,这将在Delphi7中工作


更新:除了下面的答案外,我发现TMS TAdvSmoothSplashScreen组件也能很好地处理这项任务,尽管有点复杂。

Tim,我刚刚在Vista/D2007上选择了“Windows Classic”主题进行了尝试:

Delphi中的Alpha混合启动屏幕-第2部分


没有我能看到的黑色背景。。。它看起来仍然很棒。

Bob链接到的文章给出了正确答案。由于那篇文章包含了您实际需要的相当多的额外信息,下面是我通过它创建的表单/单元(请注意,您需要GraphicEx库:

unitsplash2form;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框、ExtCtrls、GraphicEx;
类型
TSplash2=等级(TForm)
私有的
{私有声明}
过程预乘法位图(位图:TBitmap);
公众的
构造函数创建(所有者:TComponent);重写;
{公开声明}
过程CreateParams(变量参数:TCreateParams);重写;
程序执行;
结束;
变量
Splash2:TSplash2;
实施
{$R*.dfm}
{TSplash2}
构造函数TSplash2.Create(所有者:TComponent);
开始
继承;
画笔样式:=b画笔;
结束;
程序TSplash2.CreateParams(变量参数:TCreateParams);
开始
继承;
结束;
程序TSplash2.Execute;
var-exStyle:DWORD;
BitmapPos:TPoint;
位图大小:TSize;
BlendFunction:TBlendFunction;
PNG:TPNGGraphic;
Stream:TResourceStream;
开始
//启用窗口分层
exStyle:=GetWindowLongA(句柄,GWL_exStyle);
如果(exStyle和WS_EX_LAYERED=0),则
SetWindowLong(句柄、GWL_EXSTYLE、EXSTYLE或WS_EX_分层);
PNG:=TPNGGraphic.Create;
尝试
Stream:=TResourceStream.Create(HInstance,'SPLASH',RT\u RCDATA);
尝试
PNG.LoadFromStream(Stream);
最后
免费;
结束;
PreMultiplyBitmap(PNG);
ClientWidth:=PNG.Width;
ClientHeight:=巴布亚新几内亚高度;
BitmapPos:=点(0,0);
BitmapSize.cx:=客户端宽度;
BitmapSize.cy:=ClientHeight;
//设置alpha混合参数
BlendFunction.BlendOp:=AC_SRC_OVER;
BlendFunction.BlendFlags:=0;
BlendFunction.SourceConstantAlpha:=255;
BlendFunction.AlphaFormat:=AC_SRC_ALPHA;
//…还有行动!
UpdateLayeredWindow(句柄,0,nil,@BitmapSize,PNG.Canvas.Handle,
@BitmapPos,0,@BlendFunction,ULW_ALPHA);
显示
最后
巴布亚新几内亚免费;
结束;
结束;
程序TSplash2.PreMultiplyBitmap(位图:TBitmap);
变量
行,列:整数;
p:PRGBQuad;
PreMult:字节的数组[字节,字节];
开始
//预先计算a*b的所有可能值
对于行:=0到255 do
对于列:=行到255 do
开始
前置结果[行,列]:=行*列div 255;
如果(行列)那么
PreMult[Col,Row]:=PreMult[Row,Col];//a*b=b*a
结束;
对于行:=0到位图.Height-1 do
开始
Col:=位图。宽度;
p:=位图.扫描线[行];
而(Col>0)做什么
开始
p、 rgbBlue:=预结果[p.rgb,p.rgbBlue];
p、 rgbGreen:=PreMult[p.rgbReserved,p.rgbGreen];
p、 rgbreed:=PreMult[p.rgbreed,p.rgbreed];
公司(p),;
dec(Col);
结束;
结束;
结束;
结束。

+1.我最近关注了那篇文章(第1部分和第2部分),可以确认它在Vista Aero.Hrm上运行。对我来说,它似乎几乎在Aero下运行。由于未知原因,出现了窗口边框。在Delphi 7下编译;其他人也会这样吗?是的,甚至在Aero上看起来更好…:)你的驱动程序是最新的吗,尽可能最新!要明确的是,它不是一个黑色边框,它就像一个普通的表单,带有最小化、最大化和关闭按钮、标题栏等等。根据下面的评论,将BorderStyle设置为bsNone修复了视觉问题!谢谢同样,我也遇到了与上面相同的问题:在Vista Aero中,它周围有一个窗口边框。在Delphi7中编译。想法?您是否将TSplash2.BorderStyle设置为bsNone?这将完全删除窗口边框。请尝试将边框样式更改为bsNone。如果这不起作用,我以后在我的工作机器上再看一眼。更改边框样式修复了它!谢谢
unit Splash2Form;

interface

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

type
    TSplash2 = class(TForm)
    private
        { Private declarations }
    procedure PreMultiplyBitmap(Bitmap: TBitmap);
    public
        constructor Create(Owner: TComponent);override;
        { Public declarations }
        procedure CreateParams(var Params: TCreateParams);override;
    procedure Execute;
  end;

var
  Splash2: TSplash2;

implementation

{$R *.dfm}

{ TSplash2 }

constructor TSplash2.Create(Owner: TComponent);
begin
  inherited;
  Brush.Style := bsClear;
end;

procedure TSplash2.CreateParams(var Params: TCreateParams);
begin
    inherited;
end;

procedure TSplash2.Execute;
var exStyle: DWORD;
    BitmapPos: TPoint;
  BitmapSize: TSize;
  BlendFunction: TBlendFunction;
  PNG: TPNGGraphic;
  Stream: TResourceStream;
begin
  // Enable window layering
  exStyle := GetWindowLongA(Handle, GWL_EXSTYLE);
  if (exStyle and WS_EX_LAYERED = 0) then
    SetWindowLong(Handle, GWL_EXSTYLE, exStyle or WS_EX_LAYERED);

  PNG := TPNGGraphic.Create;
  try

      Stream := TResourceStream.Create(HInstance, 'SPLASH', RT_RCDATA);
      try
          PNG.LoadFromStream(Stream);
    finally
        Stream.Free;
        end;

    PreMultiplyBitmap(PNG);

      ClientWidth := PNG.Width;
    ClientHeight := PNG.Height;

      BitmapPos := Point(0, 0);
    BitmapSize.cx := ClientWidth;
      BitmapSize.cy := ClientHeight;

      // Setup alpha blending parameters
    BlendFunction.BlendOp := AC_SRC_OVER;
      BlendFunction.BlendFlags := 0;
    BlendFunction.SourceConstantAlpha := 255;
      BlendFunction.AlphaFormat := AC_SRC_ALPHA;

    // ... and action!
      UpdateLayeredWindow(Handle, 0, nil, @BitmapSize, PNG.Canvas.Handle,
      @BitmapPos, 0, @BlendFunction, ULW_ALPHA);

      Show;

  finally
    PNG.Free;
  end;
end;

procedure TSplash2.PreMultiplyBitmap(Bitmap: TBitmap);
var
  Row, Col: integer;
  p: PRGBQuad;
  PreMult: array[byte, byte] of byte;
begin
  // precalculate all possible values of a*b
  for Row := 0 to 255 do
    for Col := Row to 255 do
    begin
      PreMult[Row, Col] := Row*Col div 255;
      if (Row <> Col) then
        PreMult[Col, Row] := PreMult[Row, Col]; // a*b = b*a
    end;

  for Row := 0 to Bitmap.Height-1 do
  begin
    Col := Bitmap.Width;
    p := Bitmap.ScanLine[Row];
    while (Col > 0) do
    begin
      p.rgbBlue := PreMult[p.rgbReserved, p.rgbBlue];
      p.rgbGreen := PreMult[p.rgbReserved, p.rgbGreen];
      p.rgbRed := PreMult[p.rgbReserved, p.rgbRed];
      inc(p);
      dec(Col);
    end;
  end;
end;

end.