位图转换:创建从透明位图中排除透明面的位图

发布于 2024-11-24 18:51:51 字数 2451 浏览 1 评论 0原文

我有一组位图。它们在某种程度上都是透明的,而且我事先并不知道哪些部分是透明的。我想从原始位图创建一个新的位图,不包括透明部分,但在正方形中。我认为这张图片解释了它:

在此处输入图像描述

我知道如何从现有位图创建位图,但我不知道如何找出哪一部分是透明的以及如何使用它来实现我的目标。

这就是我计划这样做的方式:

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;

    }
}

I have a set of bitmaps. They are all transparent to some extent, and I don't know in advance which parts are transparent. I would like to create a new bitmap out of the original bitmap that excludes the transparent parts, but in a square. I think this image explains it:

enter image description here

I know how to create a bitmap out of a existing bitmap, but I don't know how to find out which part is transparent and how to use that to achieve my goal.

This is how I plan on doing this:

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; 
     }

Does anyone know how to achieve this?

EDIT:

I got it work using the following algorithm to find left, right, top and bottom values:

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;

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

智商已欠费 2024-12-01 18:51:51

我认为这更有效率,对我来说非常有用

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);
}

i think this is a bit more efficient and it works great for me

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);
}
放低过去 2024-12-01 18:51:51

如果您想要裁剪的所有图像或多或少都在原始画布的中心,我想您可以这样做:

  1. 从每个边框开始,向图像内搜索非透明像素
  2. 一旦找到左上角的像素和右下角的像素,你就会得到你想要的目标。
  3. 随意复制图像

现在,问题仍然是您如何看待透明像素。 Alpha 透明度重要吗?如果是这样,在您确定它足够透明以从图像中剪切之前需要多少 Alpha?

If all the images you want to crop are more or less in the center of the original canvas, I guess you could so something like this:

  1. Start from each border working your way inwards the image searching for non-transparent pixels
  2. Once you've found the top-left pixel and the right-bottom, you'll have your desired target.
  3. Copy the image as you please

Now, the question remains is what you consider a transparent pixel. Does alpha trasparency counts? if so, how much alpha until you decide it's transparent enough to be cut from the image?

清君侧 2024-12-01 18:51:51

要查找位图的非透明区域,请在 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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文