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

vns*_*tty 14 android draw android-canvas

我使用下面的代码在位图画布上绘制线条,同时手指触摸移动...这里我发布了部分代码,它工作正常..

如下图所示,黑色和白色位图在触摸拖动时被擦除.我使画布透明,因此父版面背景(彩色图像)变得可见.

我想知道,删除了多少区域(比如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);
Run Code Online (Sandbox Code Playgroud)
private void doDraw(Canvas c) {

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

}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)

Leo*_*dos 6

尝试使用蒙特卡罗方法估计透明区域的百分比.我认为这是一种最快速,最简单的方法.在透明度蒙版上取大约50个(取决于您需要的准确度)随机像素并检查其颜色.然后calc ans = TransparentPixelsCount/TestPixelCount.

使用路径坐标计算用户图形的平方非常困难.迭代所有像素需要很长时间.所以,恕我直言蒙特卡洛是你的选择.


iag*_*een 5

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

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

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

    }
Run Code Online (Sandbox Code Playgroud)

作为参考,下面是通过计算每个像素给出结果的慢速方法。可为测试上述估计器提供参考。

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

    }
Run Code Online (Sandbox Code Playgroud)