- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在具有不透明度(Alpha 透明度)功能的 Canvas 上绘图,如下所示:
var
Form1: TForm1;
IsDrawing: Boolean;
implementation
{$R *.dfm}
procedure DrawOpacityBrush(ACanvas: TCanvas; X, Y: Integer; AColor: TColor; ASize: Integer; Opacity: Byte);
var
Bmp: TBitmap;
I, J: Integer;
Pixels: PRGBQuad;
ColorRgb: Integer;
ColorR, ColorG, ColorB: Byte;
begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32Bit; // needed for an alpha channel
Bmp.SetSize(ASize, ASize);
with Bmp.Canvas do
begin
Brush.Color := clFuchsia; // background color to mask out
ColorRgb := ColorToRGB(Brush.Color);
FillRect(Rect(0, 0, ASize, ASize));
Pen.Color := AColor;
Pen.Style := psSolid;
Pen.Width := ASize;
MoveTo(ASize div 2, ASize div 2);
LineTo(ASize div 2, ASize div 2);
end;
ColorR := GetRValue(ColorRgb);
ColorG := GetGValue(ColorRgb);
ColorB := GetBValue(ColorRgb);
for I := 0 to Bmp.Height-1 do
begin
Pixels := PRGBQuad(Bmp.ScanLine[I]);
for J := 0 to Bmp.Width-1 do
begin
with Pixels^ do
begin
if (rgbRed = ColorR) and (rgbGreen = ColorG) and (rgbBlue = ColorB) then
rgbReserved := 0
else
rgbReserved := Opacity;
// must pre-multiply the pixel with its alpha channel before drawing
rgbRed := (rgbRed * rgbReserved) div $FF;
rgbGreen := (rgbGreen * rgbReserved) div $FF;
rgbBlue := (rgbBlue * rgbReserved) div $FF;
end;
Inc(Pixels);
end;
end;
ACanvas.Draw(X, Y, Bmp, 255);
finally
Bmp.Free;
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case Button of
mbLeft:
begin
IsDrawing := True;
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (GetAsyncKeyState(VK_LBUTTON) <> 0) and
(IsDrawing) then
begin
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsDrawing := False;
end;
绘制 DrawOpacityBrush()
过程是 Remy Lebeau 对我最近提出的上一个问题的更新:How to paint on a Canvas with Transparency and Opacity?
虽然这有效,但结果并不能满足我现在的需要。
目前,每次在 MouseMove 中调用 DrawOpacityBrush()
过程时,它都会继续绘制画笔椭圆形状。这很糟糕,因为根据您在 Canvas 上移动鼠标的速度,输出并不如预期。
这些示例图像应该能更好地说明这一点:
- 第一个红色画笔我将鼠标从 Canvas 底部快速移动到顶部。
-第二个红色笔刷我移动得慢了很多。
正如您所看到的,不透明度已正确绘制,只是圆圈也继续重复绘制。
我希望它做的是:
(1) 在椭圆周围绘制不透明线。
(2) 有一个选项可以防止绘制任何省略号。
这个模拟示例图像应该让我了解我希望如何绘制它:
3 条紫色画笔线演示了选项 (1)。
为了实现选项(2),画笔线内的圆圈不应该出现。
这样您就可以在绘图时花些时间,而不是在 Canvas 上疯狂地移动鼠标以期获得所需的结果。只有当您决定返回刚刚绘制的笔触时,该区域的不透明度才会变暗等。
如何实现这些类型的绘图效果?
我希望能够在 TImage 上绘图,因为这就是我当前正在做的事情,因此将 TCanvas 作为函数或过程中的参数传递将是理想的选择。我还将在绘图中使用 MouseDown、MouseMove 和 MouseUp 事件。
这是我使用 NGLN 提供的方法得到的输出:
不透明度似乎也应用于图像,它应该只是多段线。
最佳答案
为什么不直接画一条折线呢?
unit Unit1;
interface
uses
Windows, Classes, Graphics, Controls, Forms, ExtCtrls;
type
TPolyLine = record
Count: Integer;
Points: array of TPoint;
end;
TPolyLines = array of TPolyLine;
TForm1 = class(TForm)
PaintBox: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure PaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PaintBoxPaint(Sender: TObject);
private
FBlendFunc: BLENDFUNCTION;
FBmp: TBitmap;
FPolyLineCount: Integer;
FPolyLines: TPolyLines;
procedure AddPoint(APoint: TPoint);
function LastPoint: TPoint;
procedure NewPolyLine;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AddPoint(APoint: TPoint);
begin
with FPolyLines[FPolyLineCount - 1] do
begin
if Length(Points) = Count then
SetLength(Points, Count + 64);
Points[Count] := APoint;
Inc(Count);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FBmp := TBitmap.Create;
FBmp.Canvas.Brush.Color := clWhite;
FBmp.Canvas.Pen.Width := 30;
FBmp.Canvas.Pen.Color := clRed;
FBlendFunc.BlendOp := AC_SRC_OVER;
FBlendFunc.SourceConstantAlpha := 80;
DoubleBuffered := True;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FBmp.Free;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
FBmp.Width := PaintBox.Width;
FBmp.Height := PaintBox.Height;
end;
function TForm1.LastPoint: TPoint;
begin
with FPolyLines[FPolyLineCount - 1] do
Result := Points[Count - 1];
end;
procedure TForm1.NewPolyLine;
begin
Inc(FPolyLineCount);
SetLength(FPolyLines, FPolyLineCount);
FPolyLines[FPolyLineCount - 1].Count := 0;
end;
procedure TForm1.PaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then
begin
NewPolyLine;
AddPoint(Point(X, Y));
PaintBox.Invalidate;
end;
end;
procedure TForm1.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
if Sqr(LastPoint.X - X) + Sqr(LastPoint.Y - Y) > 30 then
begin
AddPoint(Point(X, Y));
PaintBox.Invalidate;
end;
end;
procedure TForm1.PaintBoxPaint(Sender: TObject);
var
R: TRect;
I: Integer;
begin
R := PaintBox.ClientRect;
FBmp.Canvas.FillRect(R);
for I := 0 to FPolyLineCount - 1 do
with FPolyLines[I] do
FBmp.Canvas.Polyline(Copy(Points, 0, Count));
Windows.AlphaBlend(PaintBox.Canvas.Handle, 0, 0, R.Right, R.Bottom,
FBmp.Canvas.Handle, 0, 0, R.Right, R.Bottom, FBlendFunc);
end;
end.
第二张图片展示了如何将其与背景结合起来,并通过对代码进行以下少量添加而获得,而 FGraphic
是运行时加载的图片:
procedure TForm1.PaintBoxPaint(Sender: TObject);
var
R: TRect;
I: Integer;
begin
R := PaintBox.ClientRect;
FBmp.Canvas.FillRect(R);
for I := 0 to FPolyLineCount - 1 do
with FPolyLines[I] do
FBmp.Canvas.Polyline(Copy(Points, 0, Count));
PaintBox.Canvas.StretchDraw(R, FGraphic);
Windows.AlphaBlend(PaintBox.Canvas.Handle, 0, 0, R.Right, R.Bottom,
FBmp.Canvas.Handle, 0, 0, R.Right, R.Bottom, FBlendFunc);
end;
或者,要合并已绘制的作品(例如您的Image
),请将其 Canvas 复制到PaintBox
:
procedure TForm1.PaintBoxPaint(Sender: TObject);
var
R: TRect;
I: Integer;
begin
R := PaintBox.ClientRect;
FBmp.Canvas.FillRect(R);
FBmp.Canvas.Polyline(Copy(FPoly, 0, FCount));
for I := 0 to FPolyLineCount - 1 do
with FPolyLines[I] do
FBmp.Canvas.Polyline(Copy(Points, 0, Count));
Windows.AlphaBlend(PaintBox.Canvas.Handle, 0, 0, R.Right, R.Bottom,
FBmp.Canvas.Handle, 0, 0, R.Right, R.Bottom, FBlendFunc);
end;
但就像 David 在评论中提到的那样,我也强烈建议在 PaintBox
上绘制所有内容:这就是它的用途。
关于delphi - Canvas 绘图 - 如何改进这个 Alpha 绘图例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10371787/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我不知道我问的是否可行。 我有一个带有 Color.BLACK 的 Paint 和 0.2f 的 alpha 和两个对象: 它们都使用相同的Paint。我还测试了 2 个不同的 Paint 对象,仅更
Alpha Vantage API 不提供纳斯达克指数的报价(不再?)。我感兴趣的所有其他 indizes 似乎都很有魅力。 例如,调用以下 URL(隐藏 API key )将提供 S&P 的报价(符
问:有没有办法使用默认管道正确混合 Alpha 分量? 问题:我正在将半透明表面绘制到纹理中,然后我想将该纹理传输到主框架后台缓冲区中。通常,当您使用直接的 Alpha 混合来实现透明度或抗锯齿时,会
如果我有一个底层颜色和一个 alpha 值 (C&A),并且想在屏幕上创建一个自定义 C&A,那么确定必须将什么 C&A 作为底层添加到底层之上的层的函数是什么? 编辑: 我想复制 photoshop
我想知道它们之间的区别: 给我的 UIView 分配一个颜色 <1 alpha vs 为它指定一个不透明的颜色,但给 UIView 一个 <1 的 alpha 值。 在屏幕截图上,我制作了两个 UIV
我在 OSX 10.9.4 上试图转换这个 python 正则表达式 p = "(2024 (?:(?:(?:[a-z|.]+ ?)+)) 93)"到 Unix 正则表达式以提高 grep 的速度。
我为 4 张图像制作了这个脚本,第一张图像是 alpha,但从第二张开始什么都没有显示 这是ffmpeg的代码确实有错误,但我没有。不明白:[swscaler @ 0x7fef79845e00] 使用
我正在尝试将文本绘制到具有特定 Alpha 级别的 Canvas 上,并剪辑文本并使用其自己的 Alpha 级别绘制背景颜色: ctx.globalCompositeOperation = '...'
我需要实现Lasso和Ridge回归,并通过交叉验证的方式计算超参数。我找到了执行此操作的代码,但我不太理解它。 lassocv = LassoCV(alphas=None, cv=15, max_i
我得到我的位图,将它用作着色器平铺模式。 除了要绘制的形状轮廓外,PNG 大部分是 alpha。 除了它画出轮廓,但被黑色包围,不是透明的(alpha)。 pnt.reset(); i
我正在开发一个带有 tableViewController 的应用程序。我想在我的表格 View 单元格下方添加背景图片。我想让表格 View 单元格透明,以便我的整个表格 View 可以具有自定义背
如图所示,我有 2 个具有 0.5 alpha 和 1 alpha 的按钮。我想将第一张图片中标题的 alpha 更改为 1,这可能吗? 到目前为止,我尝试了这些都不起作用: button.title
我正在尝试生成一个 python 正则表达式来表示词法分析器的标识符。我的做法是: ([a-zA-Z]([a-zA-Z]|\d)*) 当我使用它时: regex = re.compile("\s*([
我正在尝试删除所有非数字字符的字符串,并且我已阅读 Why isn't isnumeric working? ,或者我必须有一个 unicode 字符串。然而,自从 is.alnum()和is.alp
来自 hadoop 网站上的发布页面: “This release, like previous releases in hadoop-2.x series is still considered a
真的没有与 setAlpha(int) 对应的 XML 属性吗? 如果没有,有什么替代方案? 最佳答案 它比其他响应更容易。有一个 xml 值 alpha 采用 double 值。 android:a
我正在three.js 中构建一个“ Papercut ”世界。我所有的模型都是简单的“平面”,我使用带有 Alpha channel 的 PNG 对它们进行纹理处理,以将平面修剪成更令人愉悦的形状。
我想知道 Graphics2D.setComposite(..., alpha) 之间是否真的有区别和 Graphics2D.setColor(new Color(..., alpha))在 Java
我需要在两个图像之间进行转换 - 两个图像都是隐藏下面的 Sprite 的蒙版。每个面具的一部分是白色的,一部分是透明的。我需要两个图像的总 alpha 每次都为 1,这样蒙版看起来会平滑地改变其形状
我是一名优秀的程序员,十分优秀!