Android Bitmap save without transparent area

前端 未结 4 1922
暖寄归人
暖寄归人 2021-02-05 19:24

I want to save bitmap without transparent area.

Bitmap has large transparent pixel.

So i want to remove that

How can i do this?

I cant add pictur

相关标签:
4条回答
  • 2021-02-05 19:31

    Following the official doc:

    The new bitmap may be the same object as source, or a copy may have been made.

    You should take into account when you execute .recycle() with the source bitmap.

    0 讨论(0)
  • 2021-02-05 19:34

    To find the non-transparent area of your bitmap, iterate across the bitmap in x and y and find the min and max of the non-transparent region. Then crop the bitmap to those co-ordinates.

    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);
    }
    
    0 讨论(0)
  • 2021-02-05 19:39

    I took @Alvaro Menezes's answer and improved it as a Kotlin extension function. I tweaked it a bit, changed some variable names for better readability and it adds more fixes to the issue mentioned by @Ahamadullah Saikat that throws an IllegalArgumentException

    Note that reading pixels by line improve a lot the performances against reading this independently as the accepted answer suggest.

    /**
     * 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)
    }
    
    0 讨论(0)
  • 2021-02-05 19:46

    Crop transparent border with this 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);
    }
    
    0 讨论(0)
提交回复
热议问题