简体   繁体   English

如何在TImage图形中启用Alpha调平?

[英]How to enable Alpha leveling in TImage graphic?

I have TImage with a preloaded Bitmap (by PNGImage unit) with an Alpha Channel: 我有一个带有预加载位图(由PNGImage单元)和Alpha通道的TImage

在此处输入图片说明

The subject is the Great Green Dino. 主题是大绿色恐龙。 I wanted to be able to change its Alpha Level in runtime, to any value in the range. 我希望能够在运行时将其Alpha级别更改为该范围内的任何值。 Like 127 and he would look like this: 像127,他看起来像这样:

在此处输入图片说明

Following the answer to another similar question I almost felt in the skin it would work. 在回答了另一个类似问题之后,我几乎感觉到它会起作用。 But that was the result to Alpha Level 0 for example: 但这就是例如Alpha Level 0的结果:

在此处输入图片说明

So, my question. 所以,我的问题。 Could someone know how to improve the answer's routine? 有人知道如何改善答案的常规吗? Or know another way to achieve the second picture result? 还是知道另一种获得第二张图片结果的方法? Note that I want to be able change this Alpha Level property in runtime be with a Method or any other way you know 请注意,我希望能够在运行时使用方法或您知道的任何其他方式更改此Alpha Level属性

Thank you in advance... 先感谢您...

Using AlphaBlend , 使用AlphaBlend

var
  Png: TPngImage;
  Bmp: TBitmap;
  BlendFn: TBlendFunction;
begin

  // suppose you already have a master png
  Png := TPngImage.Create;
  Png.LoadFromFile(
      ExtractFilePath(Application.ExeName) + '\..\..\Attention_128.png');

  // construct a temporary bitmap with the image
  Bmp := TBitmap.Create;
  Bmp.Assign(Png);

  // prepare TImage for accepting a partial transparent image
  Image1.Picture.Bitmap.PixelFormat := pf32bit;
  Image1.Picture.Bitmap.AlphaFormat := afPremultiplied;
  Image1.Picture.Bitmap.Canvas.Brush.Color := clBlack;
  Image1.Picture.Bitmap.SetSize(Png.Width, Png.Height);

  // alpha blend the temporary bitmap to the bitmap of the image
  BlendFn.BlendOp := AC_SRC_OVER;
  BlendFn.BlendFlags := 0;
  BlendFn.SourceConstantAlpha := 128;  // set opacity here
  BlendFn.AlphaFormat := AC_SRC_ALPHA;

  winapi.windows.AlphaBlend(Image1.Picture.Bitmap.Canvas.Handle,
    0, 0, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height,
    Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, BlendFn);

  // free temporary bitmap, etc.
  ..


Commented a little, the above code produces the below image here (below image is the 'Image1'): 稍加评论,上面的代码在这里生成下面的图像(下面的图像是“ Image1”): 在此处输入图片说明

The other question involved using TBitmap to apply alpha blending to GIF images. 另一个问题涉及使用TBitmap将Alpha混合应用于GIF图像。 TPNGImage has its own native alpha support, so you don't need to involve TBitmap . TPNGImage拥有自己的本机alpha支持,因此您不需要涉及TBitmap Look at the TPNGImage.CreateAlpha() method and the TPNGImage.AlphaScanline property. 查看TPNGImage.CreateAlpha()方法和TPNGImage.AlphaScanline属性。

Try something like this: 尝试这样的事情:

procedure SetPNGAlpha(PNG: TPNGImage; Alpha: Byte);
var
  pScanline: pByteArray;
  nScanLineCount, nPixelCount : Integer;
begin
  if Alpha = 255 then begin
    PNG.RemoveTransparency;
  end else
  begin
    PNG.CreateAlpha;

    for nScanLineCount := 0 to PNG.Height - 1 do
    begin
      pScanline := PNG.AlphaScanline[nScanLineCount];
      for nPixelCount := 0 to Image.Width - 1 do
        pScanline[nPixelCount] := Alpha;
    end;
  end;

  PNG.Modified := True;
end;

procedure SetBMPAlpha(BMP: TBitmap; Alpha: Byte);
type
  pRGBQuadArray = ^TRGBQuadArray;
  TRGBQuadArray = ARRAY [0 .. 0] OF TRGBQuad;
var
  pScanLine32_src, pScanLine32_dst: pRGBQuadArray;
  nScanLineCount, nPixelCount : Integer;
  Tmp: TBitmap;
begin
  BMP.PixelFormat := pf32Bit;

  Tmp := TBitmap.Create;
  try
    Tmp.SetSize(BMP.Width, BMP.Height);
    Tmp.AlphaFormat := afDefined;

    for nScanLineCount := 0 to BMP.Height - 1 do
    begin
      pScanLine32_src := BMP.ScanLine[nScanLineCount];
      pScanLine32_dst := Tmp.Scanline[nScanLineCount];
      for nPixelCount := 0 to BMP.Width - 1 do
      begin
        pScanLine32_dst[nPixelCount].rgbReserved := Alpha;
        pScanLine32_dst[nPixelCount].rgbBlue := pScanLine32_src[nPixelCount].rgbBlue;
        pScanLine32_dst[nPixelCount].rgbRed  := pScanLine32_src[nPixelCount].rgbRed;
        pScanLine32_dst[nPixelCount].rgbGreen:= pScanLine32_src[nPixelCount].rgbGreen;
      end;
    end;

    BMP.Assign(Tmp);
  finally
    Tmp.Free;
  end;
end;

procedure SetImageAlpha(Image: TImage; Alpha: Byte);
var
  Tmp: TBitmap;
begin
  if Image.Picture.Graphic is TPNGImage then
    SetPNGAlpha(TPNGImage(Image.Picture.Graphic), Alpha)

  else if (not Assigned(Image.Picture.Graphic)) or (Image.Picture.Graphic is TBitmap) then
    SetBMPAlpha(Image.Picture.Bitmap, Alpha)

  else
  begin
    Tmp := TBitmap.Create;
    try
      Tmp.Assign(Image.Picture.Graphic);
      SetBMPAlpha(Tmp, Alpha);
      Image.Picture.Assign(Tmp);
    finally
      Tmp.Free;
    end;
  end;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM