而如何在画布上的Android描绘轨迹得到总覆盖面积?(How to get total area

2019-07-18 07:25发布

使用下面的代码林绘制位图的帆布线,而手指触摸移动......在这里,我贴出部分的代码,它工作正常..

如在下面的图像中所示,黑白位图擦除上触摸拖动..我帆布制成透明的,从而父布局背景(彩色图像)是越来越明显的。

我想知道,有多少面积被删除(如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);

private void doDraw(Canvas c) {

    c.drawBitmap(mBitmap, 0, 0,null );

}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 1;

void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}
void touch_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }

     canvas.drawPath(mPath, mDrawPaint ); //Erasing Black and white image

}
void touch_up() {
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, mDrawPaint);
    // kill this so we don't double draw
    mPath.reset();
}

Answer 1:

尝试使用蒙特卡罗方法来估算透明区域的百分比。 我认为这是做这一个最快,最简单的方法。 约需50(取决于你所需要的精度)随机像素上的透明面罩,并检查它们的颜色。 然后,计算的ANS = TransparentPixelsCount / TestPixelCount。

这是非常难以计算使用路径协调用户的图纸广场。 这是相当长遍历所有像素。 因此,恕我直言,蒙特卡洛是您最佳的选择。



Answer 2:

为了得到一个确切的(慢)的答案,你需要检查每一个像素并计算数量的像素的总数透明和鸿沟。 如果您的要求允许一些估计,它可能是最好的采样图像。

你可以缩小图像,并运行和较小的图像在上面的过程。 这有缩放操作可能经历的所有像素使得它慢的缺点。 我会建议格采样,它类似于裁员,但跳过像素。 基本上,我们均匀空间X样品在网格上在图像点。 然后计数是透明的采样点的数量。 透明百分比的估计是透明的样品的总透明样本/数。 你可以得到合理的精度(通常在5%以内),与一个小数目,说100,样品。 下面是实现此方法的代码的功能- Bm为Bitmapscale是每个轴的样本的数目,所以设置scale = 10给出了100个总样本(在10×10图象采样网格)。

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);

    }


Answer 3:

在这一种不同的方法:你可以计算出使用每个路径的大小ComputeBounds 。 然后,它应该是简单的与您的视图的大小来比较这并决定绘图%。

物权法,你需要记住的是,路径可以在自己起草,所以你必须要小心和处理,在计算中。



Answer 4:

存储所有点x和y的值在两个不同的有序集合,一个点的x值和其他的点的y值。 您绑定的最终值为点(MIN_X,MIN_Y)和点(MAX_X,MAX_Y)。



Answer 5:

您需要检测躺在绘制多边形内部的点。 这里是功能这需要数组,它包含所有的绘制点,和第二个参数是点本身即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


文章来源: How to get total area covered while drawing path on canvas android?