Android 如何在画布上绘制路径时获得总覆盖面积?

Android 如何在画布上绘制路径时获得总覆盖面积?,android,draw,android-canvas,Android,Draw,Android Canvas,我用下面的代码画线位图画布,而手指触摸移动。。。我在这里发布了部分代码,它运行良好 如下图所示,触摸拖动时会擦除黑白位图。。我使画布透明,以便父布局背景(彩色图像)变得可见 我想知道,有多少面积被擦除(比如50%或60%的位图)。。有没有办法找到这个 //Erasing paint mDrawPaint = new Paint(); mDrawPaint.setAntiAlias(true); mDrawPaint.setDither(true);

我用下面的代码画线位图画布,而手指触摸移动。。。我在这里发布了部分代码,它运行良好

如下图所示,触摸拖动时会擦除黑白位图。。我使画布透明,以便父布局背景(彩色图像)变得可见

我想知道,有多少面积被擦除(比如50%或60%的位图)。。有没有办法找到这个

//Erasing paint

         mDrawPaint = new Paint();
    mDrawPaint.setAntiAlias(true); 
    mDrawPaint.setDither(true);  
    mDrawPaint.setStyle(Paint.Style.STROKE); 
    mDrawPaint.setStrokeJoin(Paint.Join.ROUND);
    mDrawPaint.setStrokeCap(Paint.Cap.ROUND);
    mDrawPaint.setStrokeWidth(50); 
    mDrawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    BlurMaskFilter mBlur = new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL);
    mDrawPaint.setMaskFilter(mBlur);



尝试使用来估计透明区域的百分比。我认为这是一种最快、最简单的方法。在你的透明蒙版上随机选取50个像素(取决于你需要的精度),然后检查它们的颜色。然后calc ans=透明像素计数/TestPixelCount

使用路径坐标计算用户图形的平方非常困难。对所有像素进行迭代需要相当长的时间。因此,蒙特卡罗是你的选择。

要得到准确(缓慢)的答案,你需要检查每个像素,并计算出透明的数字,然后除以像素总数。如果您的需求允许进行一些估计,那么最好对图像进行采样

static public float percentTransparent(Bitmap bm, int scale) {

        final int width = bm.getWidth();
        final int height = bm.getHeight();

        // size of sample rectangles
        final int xStep = width/scale;
        final int yStep = height/scale;

        // center of the first rectangle
        final int xInit = xStep/2;
        final int yInit = yStep/2;

        // center of the last rectangle
        final int xEnd = width - xStep/2;
        final int yEnd = height - yStep/2;

        int totalTransparent = 0;

        for(int x = xInit; x <= xEnd; x += xStep) {
            for(int y = yInit; y <= yEnd; y += yStep) {
                if (bm.getPixel(x, y) == Color.TRANSPARENT) {
                    totalTransparent++;
                }
            }
        }
        return ((float)totalTransparent)/(scale * scale);

    }
您可以缩小图像的大小,并在较小的图像上运行上述过程。这样做的缺点是缩放操作可能会遍历所有像素,使其速度变慢。我建议使用网格采样,它类似于缩小尺寸,但跳过像素。基本上,我们在图像的网格上均匀地分布x个采样点。然后计算透明的采样点数量。透明百分比的估计值是总透明样本数/透明样本数。只需少量样本,例如100个样本,就可以获得合理的准确度(通常在5%以内)。下面是实现此方法的代码函数--bm是
位图
,而
比例
是每个轴的采样数,因此设置
比例=10
将给出100个总采样数(图像上的采样网格为10x10)

静态公共浮点百分比透明(位图bm,整数比例){
final int width=bm.getWidth();
最终整数高度=bm.getHeight();
//样本矩形的大小
最终int xStep=宽度/比例;
最终int yStep=高度/刻度;
//第一个矩形的中心
最终int xInit=xStep/2;
最终int Ynit=yStep/2;
//最后一个矩形的中心
最终整数xEnd=宽度-xStep/2;
最终积分值=高度-yStep/2;
int-totalTransparent=0;

对于(int x=xInit;x这方面的不同方法:您可以使用计算每个路径的大小。然后将其与视图的大小进行比较并确定图形的百分比应该很简单


JU您需要记住,路径可以在自身上绘制,因此在计算时需要小心处理。

将所有点x和y值存储在两个不同的排序集中,一个用于点的x值,另一个用于点的y值。
边界的最终值将是点(min_x,min_y)和点(max_x,max_y)。

您需要检测位于绘制多边形内的点。 下面是函数,它采用包含所有绘制点的数组,第二个参数是点本身,即x,y

// Return true if the dot { x,y } is within any of the polygons in the list

function pointInPolygons( polygons, dot )

      for (i=1, [polygons count] i++)
         {
           if (pointInPolygon( polygons[i], dot )) 
                    return true
         } 

      return false
end

// Returns true if the dot { x,y } is within the polygon 
//defined by points table { {x,y},-    --{x,y},{x,y},... }

function pointInPolygon( points, dot )
    local i, j = #points, #points
    local oddNodes = false

    for i=1, #points do
            if ((points[i].y < dot.y and points[j].y>=dot.y
                    or points[j].y< dot.y and points[i].y>=dot.y) and (points[i].x<=dot.x
                    or points[j].x<=dot.x)) then
                    if (points[i].x+(dot.y-points[i].y)/(points[j].y-points[i].y)*(points[j].x-points[i].x)<dot.x) then
                            oddNodes = not oddNodes
                    end
            end
            j = i
    end

    return oddNodes
   end
//如果点{x,y}位于列表中的任何多边形内,则返回true
函数点多边形(多边形、点)
对于(i=1,[polygons count]i++)
{
if(点多边形(多边形[i],点))
返回真值
} 
返回错误
结束
//如果点{x,y}位于多边形内,则返回true
//由点表{x,y},---x,y},{x,y},…}定义
函数点多边形(点,点)
局部i,j=#点,#点
本地节点=false
对于i=1,#点可以
如果((点[i].y=dot.y

或点[j].y=dot.y)和(点[i].xi如果我理解你的要求,你必须检查mBitmap的每个像素,看看它是否为空。如果位图大小等于设备大小,那么我必须给出的比例是什么?它与设备大小无关,它是你想要采集的样本数量。更多样本=更高的精度。比例10=100个样本,因此每个样本都要重复显示图像的百分之一。如果您想要更好,您可以尝试15或20(对于20,每个样本为.25%)。我用640x480图像在
比例=10
下进行了测试,它通常在实际值的3-4%范围内。@vnshetty.忘了在上一条评论中包括您,我添加了完整的解决方案来测试估计值。我尝试了您的代码,但得到了大约0.7778E34%的值。我在润色时调用了此函数……但是我想要这需要在触摸式移动中完成,当涉及到速度问题时,tht将更加困难…@vnshetty你使用的是什么尺度?至于速度,这就是为什么你要采取较小的样本,第二个例程将非常缓慢,但给出准确的结果。第一个例程提供了一个估计,但运行速度要快得多,尤其是对于小数量的样本您能否在android/java上共享一个实现的示例?
static public float percentTransparent(Bitmap bm, int scale) {

        final int width = bm.getWidth();
        final int height = bm.getHeight();

        // size of sample rectangles
        final int xStep = width/scale;
        final int yStep = height/scale;

        // center of the first rectangle
        final int xInit = xStep/2;
        final int yInit = yStep/2;

        // center of the last rectangle
        final int xEnd = width - xStep/2;
        final int yEnd = height - yStep/2;

        int totalTransparent = 0;

        for(int x = xInit; x <= xEnd; x += xStep) {
            for(int y = yInit; y <= yEnd; y += yStep) {
                if (bm.getPixel(x, y) == Color.TRANSPARENT) {
                    totalTransparent++;
                }
            }
        }
        return ((float)totalTransparent)/(scale * scale);

    }
static public float percentTransparent(Bitmap bm) {
        final int width = bm.getWidth();
        final int height = bm.getHeight();

        int totalTransparent = 0;
        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                if (bm.getPixel(x, y) == Color.TRANSPARENT) {
                    totalTransparent++;
                }
            }
        }
        return ((float)totalTransparent)/(width * height);

    }
// Return true if the dot { x,y } is within any of the polygons in the list

function pointInPolygons( polygons, dot )

      for (i=1, [polygons count] i++)
         {
           if (pointInPolygon( polygons[i], dot )) 
                    return true
         } 

      return false
end

// Returns true if the dot { x,y } is within the polygon 
//defined by points table { {x,y},-    --{x,y},{x,y},... }

function pointInPolygon( points, dot )
    local i, j = #points, #points
    local oddNodes = false

    for i=1, #points do
            if ((points[i].y < dot.y and points[j].y>=dot.y
                    or points[j].y< dot.y and points[i].y>=dot.y) and (points[i].x<=dot.x
                    or points[j].x<=dot.x)) then
                    if (points[i].x+(dot.y-points[i].y)/(points[j].y-points[i].y)*(points[j].x-points[i].x)<dot.x) then
                            oddNodes = not oddNodes
                    end
            end
            j = i
    end

    return oddNodes
   end