Преобразование растрового изображения: создание растрового изображения, исключающего прозрачные стороны из прозрачного растрового изображения - PullRequest
8 голосов
/ 16 июля 2011

У меня есть набор растровых изображений.Все они в некоторой степени прозрачны, и я не знаю заранее, какие части прозрачны.Я хотел бы создать новое растровое изображение из исходного растрового изображения, которое исключает прозрачные части, но в квадрате.Я думаю, что это изображение объясняет это:

enter image description here

Я знаю, как создать растровое изображение из существующего растрового изображения, но я не знаю, как выяснить, какая часть прозрачна икак использовать это для достижения моей цели.

Вот как я планирую это сделать:

public Bitmap cutImage(Bitmap image) {
        Bitmap newBitmap = null; 

        int width = image.getWidth(); 
        int height = image.getHeight(); 

        newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

        Canvas canvas = new Canvas(newBitmap); 

        //This is where I need to find out correct values of r1 and r1.

        Rect r1 = new Rect(?, ?, ?, ?);
        Rect r2 = new Rect(?, ?, ?, ?);

        canvas.drawBitmap(image, r1, r2, null);

        return newBitmap; 
     }

Кто-нибудь знает, как этого достичь?

РЕДАКТИРОВАТЬ:

Я получил работу, используя следующий алгоритм, чтобы найти левое, правое, верхнее и нижнее значения:

private int x1;
private int x2;
private int y1;
private int y2;

private void findRectValues(Bitmap image)
{
    for(int x = 0; x < image.getWidth(); x++)
    {
        for(int y = 0; y < image.getHeight(); y++)
        {
            if(image.getPixel(x, y) != Color.TRANSPARENT)
            {
                System.out.println("X1 is: " + x);
                x1 = x;
                break;
            }
        }

        if(x1 != 0)
            break;

    }

    for(int x = image.getWidth()-1; x > 0; x--)
    {
        for(int y = 0; y < image.getHeight(); y++)
        {
            if(image.getPixel(x, y) != Color.TRANSPARENT)
            {
                System.out.println("X2 is: " + x);
                x2 = x;
                break;
            }
        }

        if(x2 != 0)
            break;

    }

    for(int y = 0; y < image.getHeight(); y++)
    {
        for(int x = 0; x < image.getWidth(); x++)
        {
            if(image.getPixel(x, y) != Color.TRANSPARENT)
            {
                System.out.println("Y1 is: " + y);
                y1 = y;
                break;
            }
        }

        if(y1 != 0)
            break;

    }

    for(int y = image.getHeight()-1; y > 0; y--)
    {
        for(int x = 0; x < image.getWidth(); x++)
        {
            if(image.getPixel(x, y) != Color.TRANSPARENT)
            {
                System.out.println("Y2 is: " + y);
                y2 = y;
                break;
            }
        }

        if(y2 != 0)
            break;

    }
}

Ответы [ 3 ]

6 голосов
/ 30 сентября 2014

я думаю, что это немного более эффективно и прекрасно работает для меня

public Bitmap cropBitmapToBoundingBox(Bitmap picToCrop, int unusedSpaceColor) {
    int[] pixels = new int[picToCrop.getHeight() * picToCrop.getWidth()];
    int marginTop = 0, marginBottom = 0, marginLeft = 0, marginRight = 0, i;
    picToCrop.getPixels(pixels, 0, picToCrop.getWidth(), 0, 0,
            picToCrop.getWidth(), picToCrop.getHeight());

    for (i = 0; i < pixels.length; i++) {
        if (pixels[i] != unusedSpaceColor) {
            marginTop = i / picToCrop.getWidth();
            break;
        }
    }

    outerLoop1: for (i = 0; i < picToCrop.getWidth(); i++) {
        for (int j = i; j < pixels.length; j += picToCrop.getWidth()) {
            if (pixels[j] != unusedSpaceColor) {
                marginLeft = j % picToCrop.getWidth();
                break outerLoop1;
            }
        }
    }

    for (i = pixels.length - 1; i >= 0; i--) {
        if (pixels[i] != unusedSpaceColor) {
            marginBottom = (pixels.length - i) / picToCrop.getWidth();
            break;
        }
    }

    outerLoop2: for (i = pixels.length - 1; i >= 0; i--) {
        for (int j = i; j >= 0; j -= picToCrop.getWidth()) {
            if (pixels[j] != unusedSpaceColor) {
                marginRight = picToCrop.getWidth()
                        - (j % picToCrop.getWidth());
                break outerLoop2;
            }
        }
    }

    return Bitmap.createBitmap(picToCrop, marginLeft, marginTop,
            picToCrop.getWidth() - marginLeft - marginRight,
            picToCrop.getHeight() - marginTop - marginBottom);
}
5 голосов
/ 16 июля 2011

Если все изображения, которые вы хотите обрезать, находятся более или менее в центре оригинального холста, я думаю, вы могли бы сделать что-то вроде этого:поиск изображений для непрозрачных пикселей

Как только вы найдете верхний левый пиксель и правый нижний, у вас будет желаемая цель. Скопируйте изображение как вам угодно1008 *

Теперь остается вопрос: что вы считаете прозрачным пикселем?Имеет ли значение альфа-прозрачность?если да, сколько альфа, пока вы не решите, что он достаточно прозрачен, чтобы вырезать из изображения?

0 голосов
/ 01 февраля 2016

Чтобы найти непрозрачную область вашего растрового изображения, выполните итерацию по растровому изображению по 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);
}
...