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