Android Bitmap保存没有透明区域

use*_*874 11 android crop bitmap

我想保存没有透明区域的位图.

位图具有大的透明像素.

所以我想删除它

我怎样才能做到这一点?

我不能添加图片,所以用符号解释.

我不想裁剪功能.我希望使用过滤器

┌────────────────────────┐

│透明区域

│┌─────────

│裁剪此
└────────┘
└────────────────────────┘

sam*_*gak 24

要查找位图的非透明区域,请迭代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);
}
Run Code Online (Sandbox Code Playgroud)


Álv*_*zes 8

使用此github裁剪透明边框.

public static Bitmap crop(Bitmap bitmap) {

    int height = bitmap.getHeight();
    int width = bitmap.getWidth();
    int[] empty = new int[width];
    int[] buffer = new int[width];
    Arrays.fill(empty, 0);
    int top = 0;
    int left = 0;
    int bottom = height;
    int right = width;

    for (int y = 0; y < height; y++) {
        bitmap.getPixels(buffer, 0, width, 0, y, width, 1);
        if (!Arrays.equals(empty, buffer)) {
            top = y;
            break;
        }
    }

    for (int y = height - 1; y > top; y--) {
        bitmap.getPixels(buffer, 0, width, 0, y, width, 1);
        if (!Arrays.equals(empty, buffer)) {
            bottom = y;
            break;
        }
    }

    empty = new int[height];
    buffer = new int[height];
    Arrays.fill(empty, 0);

    for (int x = 0; x < width; x++) {
        bitmap.getPixels(buffer, 0, 1, x, 0, 1, height);
        if (!Arrays.equals(empty, buffer)) {
            left = x;
            break;
        }
    }

    for (int x = width - 1; x > left; x--) {
        bitmap.getPixels(buffer, 0, 1, x, 0, 1, height);
        if (!Arrays.equals(empty, buffer)) {
            right = x;
            break;
        }
    }

    return Bitmap.createBitmap(bitmap, left, top, right - left + 1, bottom - top + 1);
}
Run Code Online (Sandbox Code Playgroud)

  • 在这条线................................ bitmap.getPixels(缓冲液,0,1,X,顶+崩溃1,1,bufferSize); /////////////////////// java.lang.IllegalArgumentException:y + height必须<= bitmap.height() (4认同)
  • 我必须接受这个答案.结果如此之快 (2认同)

crg*_*dos 6

我接受了@Alvaro Menezes 的回答,并将其改进为 Kotlin 扩展功能。我稍微调整了一下,更改了一些变量名称以提高可读性,并为@Ahamadullah Saikat提到的引发 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)
}
Run Code Online (Sandbox Code Playgroud)