14

以下のコードを使用して、指のタッチ移動中にビットマップキャンバスに線を描画します...ここに部分的なコードを投稿しましたが、正常に動作しています..

下の画像に示すように、タッチドラッグで白黒のビットマップが消去されました.キャンバスを透明にして、親レイアウトの背景(カラー画像)が見えるようにしました。

どのくらいの領域が消去されているか知りたいです(ビットマップの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();
}
4

5 に答える 5

7

モンテカルロ法を使用して、透明領域のパーセンテージを推定してみてください。これが最も速くて簡単な方法だと思います。透明度マスクで約 50 個 (必要な精度によって異なります) のランダムなピクセルを取り、それらの色を確認します。次に、計算 ans = 透明ピクセル数/テストピクセル数。

パス座標を使用してユーザーの図面の平方を計算するのは非常に困難です。そして、すべてのピクセルを反復処理するには非常に時間がかかります。だから、私見モンテカルロはあなたの選択です。

于 2013-01-21T10:15:22.460 に答える
4

正確な(そして遅い)答えを得るには、すべてのピクセルを検査し、その数を数えて透明にし、ピクセルの総数で割る必要があります。要件である程度の見積もりが可能な場合は、画像をサンプリングするのがおそらく最善です。

画像を縮小して、小さい方の画像で上記の手順を実行できます。これには、スケーリング操作がすべてのピクセルを通過して遅くなる可能性があるという欠点があります。グリッド サンプリングをお勧めします。これはダウンサイジングに似ていますが、ピクセルをスキップします。基本的に、画像上のグリッド上に 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);

    }

参考までに、すべてのピクセルをカウントして結果を得る遅い方法を以下に示します。上記の推定器をテストする際の参考として使用できます。

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

    }
于 2013-01-23T05:59:12.283 に答える
1

描画されたポリゴンの内側にあるポイントを検出する必要があります。これは、描画されたすべての点を含む配列を受け取る関数です。2番目のパラメーターは、点自体、つまり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
于 2013-01-28T06:59:46.743 に答える
1

すべてのポイントの x 値と y 値を 2 つの異なる並べ替えられたセットに格納します。1 つはポイントの x 値用で、もう 1 つはポイントの y 値用です。境界の最終的な値は、point(min_x,min_y) と point(max_x,max_y) になります。

于 2013-01-26T19:15:40.743 に答える
1

これに対する別のアプローチ: ComputeBoundsを使用して各パスのサイズを計算できます。次に、これをビューのサイズと比較して、図面の割合を決定するのは簡単です。

ただし、パスはそれ自体の上に描画される可能性があることに注意する必要があるため、計算では注意して処理する必要があります。

于 2013-01-26T02:12:01.207 に答える