Man*_*tin 9 whitespace android image crop
给定带有alpha通道(透明度)的图像,我想删除图像边界和实际图像之间的任何空白区域.这应该在背景任务或加载屏幕中完成,具有可接受的运行时间以不削弱用户体验.
我怎样才能达到这个效果?
Man*_*tin 23
我很难找到最佳实践甚至建议来解决我的问题.基于JannGabriel的调查,他通过减小图像尺寸来调整图像的正确和底部,我设法更进一步,还删除了顶部和左侧的空白区域,并且通常可以改善精细化时间.结果很好,我目前在我的项目中使用它.我是Android编程的新手,欢迎任何有关此方法的建议.
public static Bitmap TrimBitmap(Bitmap bmp) {
int imgHeight = bmp.getHeight();
int imgWidth = bmp.getWidth();
//TRIM WIDTH - LEFT
int startWidth = 0;
for(int x = 0; x < imgWidth; x++) {
if (startWidth == 0) {
for (int y = 0; y < imgHeight; y++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
startWidth = x;
break;
}
}
} else break;
}
//TRIM WIDTH - RIGHT
int endWidth = 0;
for(int x = imgWidth - 1; x >= 0; x--) {
if (endWidth == 0) {
for (int y = 0; y < imgHeight; y++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
endWidth = x;
break;
}
}
} else break;
}
//TRIM HEIGHT - TOP
int startHeight = 0;
for(int y = 0; y < imgHeight; y++) {
if (startHeight == 0) {
for (int x = 0; x < imgWidth; x++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
startHeight = y;
break;
}
}
} else break;
}
//TRIM HEIGHT - BOTTOM
int endHeight = 0;
for(int y = imgHeight - 1; y >= 0; y--) {
if (endHeight == 0 ) {
for (int x = 0; x < imgWidth; x++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
endHeight = y;
break;
}
}
} else break;
}
return Bitmap.createBitmap(
bmp,
startWidth,
startHeight,
endWidth - startWidth,
endHeight - startHeight
);
}
Run Code Online (Sandbox Code Playgroud)
说明:对于图像的每一侧,运行FOR循环以检查像素是否不包含透明色,返回第一个非透明像素有用坐标.这样就完成了使用与修剪尺寸相反的尺寸作为基础的坐标:找到y,为每个y扫描x.
要检查Vertical-Top空白区域的结束位置,请执行以下步骤:
类似的方法用于其他维度,仅改变扫描方向.
一旦获得图像的第一个有用像素的4个坐标,Bitmap.createBitmap就调用该方法,其中原始位图作为基本图像,并且有用像素坐标为调整大小的左上和右下限制.
注1:需要注意的是坐标0,0等于它是有用的左上角.
注意2:Bitmap.createBitmap中的结束宽度和高度减少了新的起始相对坐标,否则新图像将在右下方错误地按下边界.像这样:你有一个100x100px的图像,所以结束坐标为100,100.将起始坐标更改为50,50将使精化矩形的结束坐标为150,150(100个原始坐标+ 50个修改的起点),将其推到原始图像边界之外.为了避免这种情况,新的结束坐标减少了新的起始坐标(100 + 50新的起始坐标 - 50个新的起始坐标调整)
注3:在原始答案中,使用要查找的坐标的相同维度运行给定方向上所有像素的检查,返回最高级的有用像素.检查相反的尺寸并停在第一个有用的像素处可以提高性能.
Kotlin 实现回答@Manzotin 并修复了小错误。
fun Bitmap.trimBorders(color: Int): Bitmap {
var startX = 0
loop@ for (x in 0 until width) {
for (y in 0 until height) {
if (getPixel(x, y) != color) {
startX = x
break@loop
}
}
}
var startY = 0
loop@ for (y in 0 until height) {
for (x in 0 until width) {
if (getPixel(x, y) != color) {
startY = y
break@loop
}
}
}
var endX = width - 1
loop@ for (x in endX downTo 0) {
for (y in 0 until height) {
if (getPixel(x, y) != color) {
endX = x
break@loop
}
}
}
var endY = height - 1
loop@ for (y in endY downTo 0) {
for (x in 0 until width) {
if (getPixel(x, y) != color) {
endY = y
break@loop
}
}
}
val newWidth = endX - startX + 1
val newHeight = endY - startY + 1
return Bitmap.createBitmap(this, startX, startY, newWidth, newHeight)
}
Run Code Online (Sandbox Code Playgroud)