- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个问题与我的earlier question有关就这样。
我想组合两个图层,并且仅将 alpha 应用于源图层的特定部分。我尝试的一种方法是将 SourceConstantAlpha 设置为 $ff (并让该函数使用源层中的 Alpha channel )。
这种工作方式 - 虽然速度很慢(我想我可以通过使用 ScanLines 来加快速度),但我无法弄清楚将 Alpha channel 设置为什么。文档表明计算是:
st.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
我通过猜测尝试了一些不同的值,但我的第一个问题是:如何计算 alpha 值?
在阅读了其他一些SO问题后,我遇到了TransparentBlt函数,它可以很好地(并且快速)进行遮蔽,但不能实现透明度,有没有办法结合起来这两个调用一起(也许使用第三层)?
unit MainWnd;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ControlsEx;
type
{------------------------------------------------------------------------------}
TfrmMain = class(TForm)
PaintBox1: TPaintBox;
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
{..............................................................................}
procedure copyToAlpha(const in_bitmap : TBitmap; const in_transparentColor : TColor;
const in_transparency : integer);
var
x : integer;
y : integer;
p : integer;
begin
ASSERT(in_bitmap.PixelFormat = pf32bit);
for x := 0 to in_bitmap.Width - 1 do
begin
for y := 0 to in_bitmap.Height - 1 do
begin
p := in_bitmap.Canvas.Pixels[x, y];
if TColor(p) <> in_transparentColor then
begin
in_bitmap.Canvas.Pixels[x, y] := p or (in_transparency shl 24);
end
else
in_bitmap.Canvas.Pixels[x, y] := p or ($ff shl 24);
end;
end;
end;
{..............................................................................}
procedure alphaBlendTest(
const in_target : TCanvas;
const in_width : integer;
const in_height : integer);
const
BARSIZE = 30;
var
bitmap : TBitmap;
r : TRect;
blendFn : BLENDFUNCTION;
ret : Boolean;
begin
blendFn.BlendOp := AC_SRC_OVER;
blendFn.SourceConstantAlpha := $ff;
blendFn.BlendFlags := 0;
blendFn.alphaFormat := AC_SRC_ALPHA;
bitmap := TBitmap.Create;
try
bitmap.Width := in_width;
bitmap.Height := in_height;
bitmap.PixelFormat := pf32bit;
bitmap.HandleType := bmDIB;
bitmap.TransparentColor := clFuchsia;
bitmap.Transparent := true;
bitmap.Canvas.Brush.Color := clFuchsia;
bitmap.Canvas.FillRect(Bounds(0, 0, in_width, in_height));
bitmap.Canvas.Brush.Color := clGreen;
r := Bounds(
in_width div 2 - (in_width div 3) div 2,
0,
(in_width div 3) + 1,
BARSIZE + 1);
bitmap.Canvas.Rectangle(r);
// done drawing
//copyToAlpha(bitmap, clFuchsia, 1);
ret := Windows.TransparentBlt(
in_target.Handle,
0,
0,
in_width,
in_height,
bitmap.Canvas.Handle,
0,
0,
in_width,
in_height,
clFuchsia);
//blendFn);
ASSERT(ret);
finally
bitmap.Free;
end;
end;
{..............................................................................}
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
r: TRect;
begin
PaintBox1.Canvas.Brush.Color := clBlue;
r := Bounds(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
PaintBox1.Canvas.FillRect(r);
PaintBox1.Canvas.Brush.Color := clRed;
PaintBox1.Canvas.Ellipse(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
alphaBlendTest(PaintBox1.Canvas, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
end;
end.
最佳答案
技巧:以任意比例混合相同的颜色会产生相同的颜色。
因此,最简单的方法(也许也是最有效的)是首先将透明结果绘制到临时位图,然后在目标 Canvas 上对该位图进行 alphablend。
在绘制过程中可以访问目标 Canvas :
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
const
BarSize = 30;
var
R: TRect;
Bmp: TBitmap;
BlendFunc: TBlendFunction;
begin
with PaintBox1 do
begin
R := ClientRect;
Canvas.Brush.Color := clBlue;
Canvas.FillRect(R);
Canvas.Brush.Color := clRed;
Canvas.Ellipse(R);
Bmp := TBitmap.Create;
try
Bmp.Width := Width;
Bmp.Height := Height;
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, Canvas.Handle, 0, 0,
SRCCOPY);
Bmp.Canvas.Brush.Color := clGreen;
R := Bounds(Width div 3, 0, Width div 3 + 1, BarSize + 1);
Bmp.Canvas.Rectangle(R);
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := 80;
BlendFunc.AlphaFormat := 0;
Windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height, Bmp.Canvas.Handle,
0, 0, Width, Height, BlendFunc);
finally
Bmp.Free;
end;
end;
end;
并且在绘制过程中无法访问目标 Canvas :
procedure GetRemoteBitmap(Bmp: TBitmap; Width, Height: Integer);
const
BarSize = 30;
var
R: TRect;
begin
Bmp.Canvas.Brush.Color := clFuchsia;
Bmp.Width := Width;
Bmp.Height := Height;
Bmp.TransparentColor := clFuchsia;
Bmp.Transparent := True;
Bmp.Canvas.Brush.Color := clGreen;
R := Bounds(Width div 3, 0, Width div 3 + 1, BarSize + 1);
Bmp.Canvas.Rectangle(R);
end;
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
R: TRect;
Bmp: TBitmap;
Tmp: TBitmap;
BlendFunc: TBlendFunction;
begin
with PaintBox1 do
begin
R := ClientRect;
Canvas.Brush.Color := clBlue;
Canvas.FillRect(R);
Canvas.Brush.Color := clRed;
Canvas.Ellipse(R);
Bmp := TBitmap.Create;
Tmp := TBitmap.Create;
try
GetRemoteBitmap(Bmp, Width, Height);
Tmp.Width := Width;
Tmp.Height := Height;
BitBlt(Tmp.Canvas.Handle, 0, 0, Width, Height, Canvas.Handle, 0, 0,
SRCCOPY);
TransparentBlt(Tmp.Canvas.Handle, 0, 0, Width, Height, Bmp.Canvas.Handle,
0, 0, Width, Height, ColorToRGB(clFuchsia));
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := 80;
BlendFunc.AlphaFormat := 0;
Windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height, Tmp.Canvas.Handle,
0, 0, Width, Height, BlendFunc);
finally
Tmp.Free;
Bmp.Free;
end;
end;
end;
关于delphi - Alphablend 和透明Blt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12717003/
我有一个对数据库的函数调用,我正在使用 C 和 tcl/tk,因此该函数的 tcl 调用在 C 中执行,但是当发生这种情况时,tcl 中的系统在处理查询时挂起调用以及它填充 vector 的时间,我希
我想问为什么BLT指令不是MIPS ISA的一部分。相反,他们实际上将其设为汇编程序员的伪指令。从硬件实现的角度来看,我无法识别 BLT 和 BLTZ(它是 MIPS ISA 的一部分)之间的区别。
我想问一下为什么BLT指令不是MIPS ISA的一部分。相反,他们实际上使它成为汇编程序员的伪指令。从硬件实现的角度来看,我无法识别 BLT 和 BLTZ(它是 MIPS ISA 的一部分)之间的区别
我有一个窗口,由各种对象绘制以创建分层效果(想想平视显示器,其中一个对象绘制指南针,另一个绘制网格线,另一个绘制高度计读数等)。因此,每个对象都有一个它绘制到的黑色内存位图。当我调用该对象的 Draw
在看到最新的 SO 博客文章后,我刚刚下载了 OpenSTV,内容涉及主持人选举的结果。 Jeff 写道,他使用 OpenSTV 进行选举,并提供了一个包含投票数据的选票文件 (.blt)。 我的问题
问你们一个小问题,在我的循环中,我需要使用 CMP 、 BLT 和 BGT 来比较一些值。如何在以下循环中使用所述指令? 我正在尝试使用 BGT 、 BLT 和 CMP ,因为我需要它们来使我的应用程
我已经使用 rpm 安装了用于 tcl 的 BLT,看起来安装正确。 从内心希望我可以成功执行“package require BLT”,但是,如果我尝试这样做: blt::hierbox .h 我收
我是一名优秀的程序员,十分优秀!