Android画布更改形状和文本交叉点的颜色
我正在尝试使用画布更改形状和文本交叉点的颜色。我有两个形状和一个不同的油漆文本 这是没有任何Android画布更改形状和文本交叉点的颜色,android,android-canvas,Android,Android Canvas,我正在尝试使用画布更改形状和文本交叉点的颜色。我有两个形状和一个不同的油漆文本 这是没有任何PorterDuffXfermode和PorterDuffColorFilter模式添加到任何油漆中的。我希望形状的交叉点是特定的颜色,例如白色,文本为红色或白色,如下图所示 在我的示例中,文本位于底部,中间是圆形,上面是矩形,但它并不重要,我只是想弄清楚它是如何工作的,以及如何将相交设置为特定的颜色 正如您在此图像中看到的,背景为黑色,圆圈为白色,文本为黑色。当圆重叠时,圆的交点变为黑色,文本的重叠部分
PorterDuffXfermode
和PorterDuffColorFilter
模式添加到任何油漆中的。我希望形状的交叉点是特定的颜色,例如白色,文本为红色或白色,如下图所示
在我的示例中,文本位于底部,中间是圆形,上面是矩形,但它并不重要,我只是想弄清楚它是如何工作的,以及如何将相交设置为特定的颜色
正如您在此图像中看到的,背景为黑色,圆圈为白色,文本为黑色。当圆重叠时,圆的交点变为黑色,文本的重叠部分变为白色
我可以通过以下方式实现这一点:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
如果圆形和矩形都是白色,背景是黑色。当我将背景颜色更改为任何其他颜色时,文本不可见,形状为黑色
我还想知道如何才能得到类似的结果,如在这张图片中可以重叠部分的圆圈,矩形和文字可以设置为特定的颜色
Android画布更改形状和文本交叉点的颜色
以及:
“如果圆形和矩形都是白色,背景是黑色。
当我将背景色更改为任何其他颜色时,文本不可见,形状为黑色。”
波特杜夫
- (1) 是的,我们可以使用(
): PorterDuff.Mode=Mode.ADD模式。添加)
- (2)
背景必须透明,画布
才能工作。 如果您需要任何其他背景色,那么我们需要在单独的合成
画布上进行合成。 然后我们将图形复制到原始的
画布
PorterDuff
决定混合颜色;O():
(Q1:)“可以将圆形、矩形和文本的重叠部分设置为
特定颜色?”
- (A1:)是的,它是可以做到的(需要付出很大的努力)。几乎完成了,但有信心它可以做到。以下是几乎完成的图片(我必须使用这个答案中的几乎所有内容,必须有一个更简单的方法……:
public Rect mBound = new Rect(0 , 0 , 10 , 10);
public RectF a1 = new Rect(0f , 0f , 10f, 10f);
public RectF b1 = new Rect(5f , 5f , 20f, 20f);
public RectF c1 = new Rect(30f, 30f, 40f, 40f);
int boolean hit = false;
int boolean intersect = false;
hit = hitTest(20,15); // returns false
hit = hitTest(5,5); // returns true
intersect = intersectsTest(a1,b1);// returns true
intersect = intersectsTest(a1,c1);// returns false
public boolean hitTest(int x, int y)
{
return mBound.contains(x, y);
}//
// Returns true if the two specified rectangles intersect
public boolean intersectsTest(RectF a, RectF b)
{
return intersects ( a, b);
}//
笔记
你说你想了解更多关于彩色绘画的知识,以下是我玩过的一些东西
使用setColorFilter
和ColorMatrixColorFilter
进行实验:
textPaint.setColorFilter(new ColorMatrixColorFilter(getColorMatrix5()));//custom 5
//custom 5
private ColorMatrix getColorMatrix5()
{
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);//make it greyscale
ColorMatrix blueMatrix = new ColorMatrix(new float[] {
0, 0, 0, 0, 0, // red
0, 0, 0, 0, 0, // green
1, 1, 1, 1, 1, // blue
1, 1, 1, 1, 1 // alpha
});
// Convert, then scale and clamp
colorMatrix.postConcat(blueMatrix);
return colorMatrix;
}//getColorMatrix1
定制PorterDuff
听起来您需要一个自定义PorterDuff
。下面是一些代码,让您了解如何编写它(Android
使用C++
编写的库)
公共类MyPorterDuffMode
{
公共位图应用程序预览模式(位图srcBmp、位图destBmp)
{
int width=srcBmp.getWidth();
int height=srcBmp.getHeight();
int srcPixels[]=新int[宽度*高度];
int destPixels[]=新int[宽度*高度];
int-resultPixels[]=新int[width*height];
int aS=0,rS=0,gS=0,bS=0;
int-rgbS=0;
int aD=0,rD=0,gD=0,bD=0;
int rgbD=0;
尝试
{
getPixels(srcPixels,0,宽度,0,0,宽度,高度);
getPixels(destPixels,0,宽度,0,0,宽度,高度);
srcBmp.recycle();
destBmp.recycle();
}
捕获(IllegalArgumentException e)
{
}
捕获(阵列索引边界外异常e)
{
}
对于(int y=0;y>24)&0xff;
rS=(rgbS>>16)和0xff;
gS=(rgbS>>8)和0xff;
bS=(rgbS)&0xff;
rgbD=像素[y*宽度+x];
aD=((rgbD>>24)和0xff);
rD=(rgbD>>16)和0xff;
gD=(rgbD>>8)和0xff;
bD=(rgbD)&0xff;
//覆盖模式
rS=覆盖字节(rD、rS、aS、aD);
gS=叠加字节(gD、gS、aS、aD);
bS=覆盖字节(bD、bS、aS、aD);
aS=aS+aD-数学圆整((aS*aD)/255f);
结果像素[y*宽度+x]=((int)谢谢你的回答。我实际上想做的是将相交点改为特定颜色,如第三幅图像。我不想添加红色和蓝色以获得品红的结果颜色。如果可能的话,我也在寻找一种没有位图和第二张画布的方法。例如,我希望矩形和圆形的相交点为白色,文本颜色为红色。我想要实现在第三张图片中所做的。你能提供一个第三张图片的例子吗?事实上,这对我来说已经足够得到像第三张图片一样的精确结果了。但是如果我能学会如何用更多的控制来操纵交叉点,那就更好了。如果我的问题没有更具体的答案,我会接受你的答案并奖励你。谢谢或者你的努力。你的答案正是我想要的。我需要定制的交叉点颜色,并添加黑白色的片段,因为有人总是在没有阅读的情况下对问题投反对票。我问的问题在SO中不可用。再次感谢,我接受了你的答案并获得了赏金。问候。你好,色雷斯人你能分享你的鳕鱼吗我也在做这个项目,但是我的圈子进展很慢。你能帮我吗?我是初学者。
textPaint.setColorFilter(new ColorMatrixColorFilter(getColorMatrix5()));//custom 5
//custom 5
private ColorMatrix getColorMatrix5()
{
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);//make it greyscale
ColorMatrix blueMatrix = new ColorMatrix(new float[] {
0, 0, 0, 0, 0, // red
0, 0, 0, 0, 0, // green
1, 1, 1, 1, 1, // blue
1, 1, 1, 1, 1 // alpha
});
// Convert, then scale and clamp
colorMatrix.postConcat(blueMatrix);
return colorMatrix;
}//getColorMatrix1
public class MyPorterDuffMode
{
public Bitmap applyOverlayMode(Bitmap srcBmp, Bitmap destBmp)
{
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
int srcPixels[] = new int[width * height];
int destPixels[] = new int[width * height];
int resultPixels[] = new int[width * height];
int aS = 0, rS = 0, gS = 0, bS = 0;
int rgbS = 0;
int aD = 0, rD = 0, gD = 0, bD = 0;
int rgbD = 0;
try
{
srcBmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
destBmp.getPixels(destPixels, 0, width, 0, 0, width, height);
srcBmp.recycle();
destBmp.recycle();
}
catch(IllegalArgumentException e)
{
}
catch(ArrayIndexOutOfBoundsException e)
{
}
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
rgbS = srcPixels[y*width + x];
aS = (rgbS >> 24) & 0xff;
rS = (rgbS >> 16) & 0xff;
gS = (rgbS >> 8) & 0xff;
bS = (rgbS ) & 0xff;
rgbD = destPixels[y*width + x];
aD = ((rgbD >> 24) & 0xff);
rD = (rgbD >> 16) & 0xff;
gD = (rgbD >> 8) & 0xff;
bD = (rgbD ) & 0xff;
//overlay-mode
rS = overlay_byte(rD, rS, aS, aD);
gS = overlay_byte(gD, gS, aS, aD);
bS = overlay_byte(bD, bS, aS, aD);
aS = aS + aD - Math.round((aS * aD)/255f);
resultPixels[y*width + x] = ((int)aS << 24) | ((int)rS << 16) | ((int)gS << 8) | (int)bS;
}
}
return Bitmap.createBitmap(resultPixels, width, height, srcBmp.getConfig());
}
// kOverlay_Mode
int overlay_byte(int sc, int dc, int sa, int da)
{
int tmp = sc * (255 - da) + dc * (255 - sa);
int rc;
if (2 * dc <= da)
{
rc = 2 * sc * dc;
}
else
{
rc = sa * da - 2 * (da - dc) * (sa - sc);
}
return clamp_div255round(rc + tmp);
}
int clamp_div255round(int prod)
{
if (prod <= 0)
{
return 0;
}
else if (prod >= 255*255)
{
return 255;
}
else
{
return Math.round((float)prod/255);
}
}
}//class MyPorterDuffMode