Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android画布更改形状和文本交叉点的颜色_Android_Android Canvas - Fatal编程技术网

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