- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我整晚都在试图弄清楚这一点,但在谷歌上找到的答案与关于 Android Canvas 的非常具体的问题有关,我还没有找到关于这个主题的任何 101 解释。甚至 Android 文档也使用位图而不是绘制形状。
具体问题:
我需要在 Canvas 上绘制一个椭圆和一条路径。并根据 documentation 颜色源输出一种颜色,输出另一种颜色和重叠区域,无论是源输入还是目标输入,第三种颜色。我正在尝试在屏幕外 Canvas 中完成所有这些工作。但是上面的一些步骤会出现问题,并且在尝试以任何方式组合它们时会变得更糟。
Bitmap bmp = Bitmap.CreateBitmap (720, 720, Bitmap.Config.Argb8888);
Canvas c = new Canvas (bmp);
Paint paint = new Paint ();
paint.SetARGB (255, 255, 0, 0);
c.DrawOval (200, 200, 520, 520, paint); //assumed destination
paint.SetARGB (255, 0, 0, 255);
paint.SetXfermode (new PorterDuffXfermode (PorterDuff.Mode.*)); //replace mode here
paint.SetStyle (Paint.Style.Fill);
Path path = new Path ();
path.MoveTo (c.Width / 2f, c.Height / 2f);
foreach (var m in measurements) {
//calculations
float x = xCalculatedValue
float y = yCalculatedValue
path.LineTo (x, y);
}
path.LineTo (c.Width / 2f, c.Height / 2f);
c.DrawPath (path, paint); //assumed source
Bitmap DrawGraphBitmapOffscreen ()
{
Bitmap bmp = Bitmap.CreateBitmap (720, 720, Bitmap.Config.Argb8888);
Canvas c = new Canvas (bmp);
// Replace with calculated path
Path path = new Path ();
path.MoveTo (c.Width / 2f, c.Height / 2f);
path.LineTo (263, 288);
path.LineTo (236, 202);
path.LineTo (312, 249);
path.LineTo (331, 162);
path.LineTo (374, 240);
path.LineTo (434, 174);
path.LineTo (431, 263);
path.LineTo (517, 236);
path.LineTo (470, 312);
path.LineTo (557, 331);
path.LineTo (479, 374);
path.LineTo (545, 434);
path.LineTo (456, 431);
path.LineTo (483, 517);
path.LineTo (407, 470);
path.LineTo (388, 557);
path.LineTo (345, 479);
path.LineTo (285, 545);
path.LineTo (288, 456);
path.LineTo (202, 483);
path.LineTo (249, 407);
path.LineTo (162, 388);
path.LineTo (240, 345);
path.LineTo (174, 285);
path.LineTo (263, 288);
path.Close ();
Paint paint = new Paint ();
paint.SetARGB (255, 255, 0, 0);
paint.SetStyle (Paint.Style.Fill);
c.DrawPath (path, paint);
paint.SetARGB (255, 0, 0, 255);
paint.SetXfermode (new PorterDuffXfermode (PorterDuff.Mode.SrcIn));
c.DrawOval (200, 200, 520, 520, paint);
paint.SetARGB (255, 255, 255, 255);
paint.SetXfermode (new PorterDuffXfermode (PorterDuff.Mode.DstOver));
c.DrawOval (200, 200, 520, 520, paint);
return bmp;
}
最佳答案
What do PorterDuff source and destination refer to when drawing on canvas?
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
//Set the background color
canvas.DrawARGB(255, 139, 197, 186);
int canvasWidth = canvas.Width;
int r = canvasWidth / 3;
//Draw a yellow circle
paint.Color = Color.Yellow;
canvas.DrawCircle(r, r, r, paint);
//Draw a blue rectangle
paint.Color = Color.Blue;
canvas.DrawRect(r, r, r * 2.7f, r * 2.7f, paint);
}
OnDraw
方法,设置一个绿色背景,然后画一个黄色圆圈和一个蓝色矩形,效果:
Canvas
时的正常程序。 ,我没有使用任何
PorterDuffXfermode
,我们来分析一下它的过程:
canvas.DrawARGB(255, 139, 197, 186)
方法绘制整体Canvas
使用单一颜色时,此 Canvas 中的每个像素都具有相同的 ARGB
值(value):(255, 139, 197, 186)
.由于 ARGB
中的 alpha 值是 255 而不是 0,所以每个像素都是不透明的。 canvas.DrawCircle(r, r, r, paint)
方法,Android会在你定义的位置画一个黄色圆圈。 ARGB值为(255,139,197,186)
的所有像素在这个圆圈中将替换为黄色像素。(255,139,197,186)
的像素。是目的地。 我稍后会解释。 canvas.DrawRect(r, r, r * 2.7f, r * 2.7f, paint)
后方法,Android会绘制一个蓝色矩形,这个矩形中的所有像素都是蓝色的,这些蓝色像素会替换相同位置的其他像素。所以蓝色矩形可以在Canvas
上绘制. Xfermode
, PorterDuff.Mode.Clear
:
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
//Set the background color
canvas.DrawARGB(255, 139, 197, 186);
int canvasWidth = canvas.Width;
int r = canvasWidth / 3;
//Draw a yellow circle
paint.Color = Color.Yellow;
canvas.DrawCircle(r, r, r, paint);
//Use Clear as PorterDuffXfermode to draw a blue rectangle
paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
paint.Color = Color.Blue;
canvas.DrawRect(r, r, r * 2.7f, r * 2.7f, paint);
paint.SetXfermode(null);
this.SetLayerType(LayerType.Software, null);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//I found that PorterDuff.Mode.Clear doesn't work with hardware acceleration, so you have add this code
}
canvas.DrawARGB(255, 139, 197, 186)
绘制整体的方法Canvas
作为单一颜色,每个像素都是不透明的。 canvas.DrawCircle(r, r, r, paint)
画黄色的方法Canvas
. paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear))
,设置油漆PorterDuff
型号为Clear
. canvas.DrawRect(r, r, r * 2.7f, r * 2.7f, paint)
绘制一个蓝色矩形,最后它显示一个白色矩形。 canvas.DrawXXX()
方法我们将通过
Paint
参数,Android执行draw方法时会检查paint是否有
Xfermode
模式。如果没有,则图形将直接覆盖
Canvas
中的像素。在同一个位置。否则,它将更新
Canvas
中的像素。根据
Xfermode
模式。
canvas.DrawCirlce()
方法,
Paint
没有
Xfermode
模型,所以黄色圆圈直接覆盖了
Canvas
中的像素.但是当我们调用
canvas.DrawRect()
绘制一个矩形,
Paint
有一个
Xfermode
值(value)
PorterDuff.Mode.Clear
.
然后Android会在内存中绘制一个矩形,这个矩形中的像素有一个名字:Source .
内存中的矩形在Canvas
中有对应的矩形,对应的矩形称为:ARGB
的值源像素的值和
ARGB
的值根据
Xfermode
定义的规则计算目标像素的,它将计算最终的 ARGB 值。然后更新
ARGB
最终
ARGB
的目标像素的值值(value)。
Xfermode
是
PorterDuff.Mode.Clear
,它需要目标像素
ARGB
变成
(0,0,0,0)
,这意味着它是透明的。所以我们使用
canvas.DrawRect()
方法在
Canvas
中绘制一个透明矩形, 自
Activity
本身具有白色背景颜色,因此它将显示一个白色矩形。
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
paint.SetARGB(255, 255, 0, 0);
RectF oval2 = new RectF(60, 100, 300, 200);
canvas.DrawOval(oval2, paint);
paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.*));
Path path = new Path();
paint.SetStyle(Paint.Style.Fill);
paint.SetARGB(255, 0, 0, 255);
path.MoveTo(180, 50);
path.LineTo(95, 240);
path.LineTo(255, 240);
path.Close();
this.SetLayerType(LayerType.Software, null);
canvas.DrawPath(path, paint);
paint.SetXfermode(null);
}
Xfermode
,它们的作用:
Xfermode
达到你的效果。
关于android - 在 Canvas 上绘图时,PorterDuff 源和目标指的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46227332/
我有一个扩展 LinearLayout 的类,无法弄清楚如何让 PorterDuff.Mode 使用这段代码: this.getBackground().setColorFilter(Color.pa
我正在尝试使用定义为 9-patch 的 mask 来遮盖 FrameLayout。然而,尽管它在 5.0+ 的旧版本(例如 4.4.4)上运行良好,但补丁会留下不透明的黑色背景。除了在渲染到屏幕或恢
在我的项目中,我有一张位图填满了整个屏幕。在此位图上,我用 绘制了一条路径 android.graphics.Canvas.drawPath(Path path, Paint paint) 绘制是为了
我不想使用状态选择器。我想编写通用代码以将滤镜应用于文本颜色,无论原始颜色是什么。 这实际上是按下时着色按钮的一部分。我了解到我可以轻松地为 ImageButton 着色: imageButton.s
我有一个黑白 ninepatch 可绘制作为 View 的背景,我想在其上应用一种颜色,如半透明覆盖层,使绘图可见但在其上应用所需的颜色。 我认为 drawable.setColorFilter(co
我正在开发在 Canvas 上绘图的应用程序,类似于来自 Android SDK 的 Finger Paint 演示。我的问题是当我使用 PorterDuff.Mode.CLEAR 时。在绘画和 Ca
我尝试使用 Porter-Duff Xfermodes 删除我的 Android 应用程序中的部分位图。 我有一个绿色背景,上面覆盖了一张蓝色位图。当我触摸屏幕时,应该在覆盖位图中创建一个“孔”,使绿
图像透明的地方,我变黑了...... 我已经用位图 Canvas 上的另一个图像对图像进行了同样的处理,并且效果很好,但是当我尝试在自定义 View 的 onDraw 内部进行屏蔽时,它不起作用。 我
我对 PorterDuff.Mode.Multiply 有疑问,似乎所有 alpha channel 都设置为“黑色”。这是预期的吗?在 photoshop/gimp 等中,效果将透明度保留在应有的位
我正在使用的应用程序需要一些帮助。我正在尝试创建一个绘画应用程序,几天前我注意到了一个问题,现在我决定进行一些研究来解决它。当我使用 PorterDuff.Mode.CLEAR 将我的画笔用作橡皮擦时
我创建了一个可以水平滚动的 View (通过 ViewGroup)。在左侧,我有行的图像(一种标题)。当我向左 ScrollView 时,我的项目移动到行的标题下。因为我的标题背景是透明的,所以我看到
我正在尝试从 Android SDK 创建一个类似于 Finger Paint 示例的应用程序。我试图在我的测试应用程序中实现撤消/重做功能,并在这个问题中使用了公认的答案:Android Finge
我在Android Studio 1.4中创建了一个Navigation Drawer Activity后,IDE自动生成了一些xml文件。 现在有一个问题: 布局编辑器中的图形预览可能不准确:- 不
我整晚都在试图弄清楚这一点,但在谷歌上找到的答案与关于 Android Canvas 的非常具体的问题有关,我还没有找到关于这个主题的任何 101 解释。甚至 Android 文档也使用位图而不是绘制
在默认的 Android 主题下,我通过 设置了三个自定义彩色按钮 button.getBackground().setColorFilter(customColor, PorterDuff.Mode
我能否让它绘制路径,我移动手指用透明线删除,或者根本不绘制? 这就是我如何实例化我的橡皮擦: OnClickListener eraseListener = new OnClickListener(
我有一个 alpha 蒙版,我想将这个蒙版用作橡皮,当用户在屏幕上触摸时,位图的那部分应该作为 alpha 蒙版的形状被删除。我试过了,但它总是将整个位图作为掩码而不是 alpha 部分。稍后,用户将
我想为我的绘画应用实现橡皮擦。我可以用下面的代码删除 paint.setColor(0x00000000); paint.setAlpha(0x00); 但是删除后,当您再次开始绘画时,它无法正常
我想知道 PorterDuff.Mode 在 android 图形中的含义。 我知道这是一种传输方式。 我也知道,它有 DST_IN、Multiply 等属性。 最佳答案 这是一篇由 Google 工
我在我的 GridView 中加载了一些图像,我想使用屏幕混合模式为它们应用微红色。 在我的适配器中我有这段代码: ImageView image = (ImageView) findViewById
我是一名优秀的程序员,十分优秀!