Android位图不带透明区域保存
我想保存没有透明区域的位图 位图具有较大的透明像素 所以我想把它去掉 我该怎么做 我不能添加图片,所以用符号解释 我不想裁剪函数。 我希望使用过滤器 ┌────────────────────────┐ │ 透明区 │ ┌────────┐ │ 裁剪此Android位图不带透明区域保存,android,bitmap,crop,Android,Bitmap,Crop,我想保存没有透明区域的位图 位图具有较大的透明像素 所以我想把它去掉 我该怎么做 我不能添加图片,所以用符号解释 我不想裁剪函数。 我希望使用过滤器 ┌────────────────────────┐ │ 透明区 │ ┌────────┐ │ 裁剪此 └────────┘ └────────────────────────┘ 要查找位图的非透明区域,请在位图的x和y方向上迭代,并找到非透明区域的最小值和最大值。然后将位图裁剪到这些坐标 Bitmap CropBitmapTransp
└────────┘
└────────────────────────┘ 要查找位图的非透明区域,请在位图的x和y方向上迭代,并找到非透明区域的最小值和最大值。然后将位图裁剪到这些坐标
Bitmap CropBitmapTransparency(Bitmap sourceBitmap)
{
int minX = sourceBitmap.getWidth();
int minY = sourceBitmap.getHeight();
int maxX = -1;
int maxY = -1;
for(int y = 0; y < sourceBitmap.getHeight(); y++)
{
for(int x = 0; x < sourceBitmap.getWidth(); x++)
{
int alpha = (sourceBitmap.getPixel(x, y) >> 24) & 255;
if(alpha > 0) // pixel is not 100% transparent
{
if(x < minX)
minX = x;
if(x > maxX)
maxX = x;
if(y < minY)
minY = y;
if(y > maxY)
maxY = y;
}
}
}
if((maxX < minX) || (maxY < minY))
return null; // Bitmap is entirely transparent
// crop bitmap to non-transparent area and return:
return Bitmap.createBitmap(sourceBitmap, minX, minY, (maxX - minX) + 1, (maxY - minY) + 1);
}
位图CropBitmapTransparency(位图源位图)
{
int minX=sourceBitmap.getWidth();
int minY=sourceBitmap.getHeight();
int maxX=-1;
int maxY=-1;
对于(int y=0;y>24)和255;
如果(alpha>0)//像素不是100%透明的
{
if(xmaxX)
maxX=x;
if(ymaxY)
maxY=y;
}
}
}
if((maxX
使用此选项裁剪透明边框
公共静态位图裁剪(位图){
int height=bitmap.getHeight();
int width=bitmap.getWidth();
int[]空=新int[宽度];
int[]缓冲区=新的int[宽度];
数组。填充(空,0);
int-top=0;
int左=0;
内底=高度;
int right=宽度;
对于(int y=0;y顶部;y--){
getPixels(缓冲区,0,宽度,0,y,宽度,1);
如果(!array.equals(空,缓冲区)){
底部=y;
打破
}
}
空=新整数[高度];
缓冲区=新整数[高度];
数组。填充(空,0);
对于(int x=0;xleft;x--){
getPixels(缓冲区,0,1,x,0,1,高度);
如果(!array.equals(空,缓冲区)){
右=x;
打破
}
}
返回Bitmap.createBitmap(位图,左,上,右-左+1,下-上+1);
}
我将其作为Kotlin扩展函数进行了改进。我对它进行了一些调整,更改了一些变量名以提高可读性,并为所提到的引发IllegalArgumentException的问题添加了更多修复
请注意,按照公认的答案,逐行读取像素可以大大提高独立读取像素的性能
/**
* Trims a bitmap borders of a given color.
*
*/
fun Bitmap.trim(@ColorInt color: Int = Color.TRANSPARENT): Bitmap {
var top = height
var bottom = 0
var right = width
var left = 0
var colored = IntArray(width, { color })
var buffer = IntArray(width)
for (y in bottom until top) {
getPixels(buffer, 0, width, 0, y, width, 1)
if (!Arrays.equals(colored, buffer)) {
bottom = y
break
}
}
for (y in top - 1 downTo bottom) {
getPixels(buffer, 0, width, 0, y, width, 1)
if (!Arrays.equals(colored, buffer)) {
top = y
break
}
}
val heightRemaining = top - bottom
colored = IntArray(heightRemaining, { color })
buffer = IntArray(heightRemaining)
for (x in left until right) {
getPixels(buffer, 0, 1, x, bottom, 1, heightRemaining)
if (!Arrays.equals(colored, buffer)) {
left = x
break
}
}
for (x in right - 1 downTo left) {
getPixels(buffer, 0, 1, x, bottom, 1, heightRemaining)
if (!Arrays.equals(colored, buffer)) {
right = x
break
}
}
return Bitmap.createBitmap(this, left, bottom, right - left, top - bottom)
}
在官方文件之后: 新位图可能是与源相同的对象,或者可能已经制作了副本
在使用源位图执行
.recycle()
时,您应该考虑到这一点。您想用颜色填充透明区域吗?不,我想使用过滤器裁剪没有透明区域的位图。请尝试以下回答:非常好,亲爱的!最近几天才发现这件事!再次感谢你!这真的很棒。但执行起来需要一段时间。这是完成此任务的最快方法吗?@nitech如果在位图上调用getPixels()或copyPixelsToBuffer(),则可以遍历像素数据,而不必为每个像素调用getPixel()。这应该会加快速度,但会使事情复杂化,因为你必须考虑步幅,自己做像素索引。使用本机代码可能会更快,但似乎不必要的复杂。谢谢。我会对速度做更多的研究。@nitech更改算法也会加快速度。因为它做了很多不必要的检查。例如,您可以从顶部向下扫描,然后从底部向上扫描以找到最小值和最大值y,然后在剩余区域中扫描每行,但在每行中仅检查小于当前最小值x且大于当前最大值x的区域以计算最小值和最大值x。但是,读取内存的顺序可能会影响性能。您是否可以在此处添加代码片段,以便其他人不必访问github repo?完成;)@MartinGottweis。此代码不读取所有像素,只对垂直和水平矩阵进行切片,因此在我的测试中速度更快。在这一行上崩溃。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。位图.getPixels(缓冲区,0,1,x,top+1,1,bufferSize);////java.lang.IllegalArgumentException:y+高度必须为
/**
* Trims a bitmap borders of a given color.
*
*/
fun Bitmap.trim(@ColorInt color: Int = Color.TRANSPARENT): Bitmap {
var top = height
var bottom = 0
var right = width
var left = 0
var colored = IntArray(width, { color })
var buffer = IntArray(width)
for (y in bottom until top) {
getPixels(buffer, 0, width, 0, y, width, 1)
if (!Arrays.equals(colored, buffer)) {
bottom = y
break
}
}
for (y in top - 1 downTo bottom) {
getPixels(buffer, 0, width, 0, y, width, 1)
if (!Arrays.equals(colored, buffer)) {
top = y
break
}
}
val heightRemaining = top - bottom
colored = IntArray(heightRemaining, { color })
buffer = IntArray(heightRemaining)
for (x in left until right) {
getPixels(buffer, 0, 1, x, bottom, 1, heightRemaining)
if (!Arrays.equals(colored, buffer)) {
left = x
break
}
}
for (x in right - 1 downTo left) {
getPixels(buffer, 0, 1, x, bottom, 1, heightRemaining)
if (!Arrays.equals(colored, buffer)) {
right = x
break
}
}
return Bitmap.createBitmap(this, left, bottom, right - left, top - bottom)
}