Как получить общую площадь при рисовании на холсте андроида?

Я использую ниже код, чтобы нарисовать линию на холсте растрового изображения, пока движение пальцем коснется … здесь я опубликовал частичный код, и он отлично работает.

Как показано на рисунке ниже, черно-белое растровое изображение стирается при касании. Я сделал холст прозрачным, так что становится видимым исходный макет (цветное изображение).

Я хочу знать, сколько области стирается (например, 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(); } 

Solutions Collecting From Web of "Как получить общую площадь при рисовании на холсте андроида?"

Попытайтесь использовать метод Монте-Карло для оценки процента прозрачной области. Я думаю, что это самый быстрый и простой способ сделать это. Возьмите около 50 (в зависимости от требуемой точности) случайных пикселей на маске прозрачности и проверьте их цвет. Затем выполните вычисление ans = TransparentPixelsCount / TestPixelCount.

Очень сложно вычислить квадрат чертежей пользователя, используя координаты пути. И довольно много времени для повторения всех пикселей. Итак, IMHO Monte Carlo – ваш выбор.

Чтобы получить точный (и медленный) ответ, вам нужно проверить каждый пиксель и подсчитать количество прозрачных и разделить на общее количество пикселей. Если ваши требования позволяют оценить, вероятно, лучше всего пробовать изображение.

Вы можете уменьшить размер изображения и выполнить и описанную выше процедуру на меньшем изображении. Это имеет тот недостаток, что операция масштабирования может проходить через все пиксели, что замедляет работу. Я бы рекомендовал выборку сетки, она похожа на сокращение, но пропускает пиксели. В принципе, мы равномерно размещаем x выборок точек на сетке над изображением. Затем подсчитайте количество прозрачных точек выборки. Оценка прозрачного процента – это суммарные прозрачные образцы / количество прозрачных образцов. Вы можете получить разумную точность (обычно в пределах 5%) с небольшим количеством, скажем, 100 образцов. Вот функция кода, которая реализует этот метод: bm – Bitmap а scale – количество выборок на ось, поэтому установка 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); } 

Другой подход к этому: вы можете рассчитать размер каждого пути с помощью ComputeBounds . Тогда это должно быть просто сравнить это с размером вашего взгляда и решить% чертежа.

Jus вам нужно иметь в виду, что путь можно нарисовать над собой, поэтому вам нужно быть осторожным и обрабатывать это при вычислении.

Сохраните все значения 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