裁剪图像的透明边

时间:2017-11-07 18:13:18

标签: java crop bufferedimage alpha-transparency

我正在尝试创建一个仅从右侧和左侧裁剪BufferedImage的透明边缘的函数。

所以,我在网上发现了这种方法,但我真的不明白填充的pixels[]数组是什么?我假设它是每个像素的alpha,red,green,blue值(通过4中的(j*width+i)*4判断,它选择每个第四个元素),但是这个数组的长度是{{1对于299208图像(我知道它不是2的幂,只是忽略它)。

那么,我如何实现这一点,我很好奇这个像素阵列中实际存储了什么?

68x67

我在上面的代码中基本上做的是从左侧和右侧扫描图像,检查alpha值并标记我需要裁剪的距离,但它会抛出异常,因为循环完成没有检测任何不透明像素(我正在裁剪的图像肯定不透明)。

我做了检查,发现大于public static BufferedImage trimHorizontally(BufferedImage img) { final byte[] pixels = ((DataBufferByte)img.getRaster().getDataBuffer()).getData(); int width = img.getWidth(), height = img.getHeight(); int x0, x1; int j, i; leftLoop: for(i = 0; i < width; i++) { for(j = 0; j < height; j++) { if(pixels[(j*width+i)*4] != 0) { break leftLoop; } } } x0 = i; rightLoop: for(i = width-1; i >= 0; i--) { for(j = 0; j < height; j++) { if(pixels[(j*width+i)*4] != 0) { break rightLoop; } } } x1 = i+1; return img.getSubimage(x0, 0, x1-x0, height); } 的alpha值实际上高于0数组的35000索引,并且pixels[]计算我只能到达(j*width+i)*4 ....

1 个答案:

答案 0 :(得分:1)

快速修复

你可以用:

制作像素
final int[] pixels = ((DataBufferInt)img.getAlphaRaster().getDataBuffer()).getData();

并删除*4中的(j*width+i)*4。这只会使您的pixels[]仅包含Alpha值,而不包含RGB。

然而,更安全(没有不安全的DataBuffer演员表),更易读的解决方案:

首选版本

我所做的更改是停止使用可怕的byte数组,而只需使用getRGB()方法。可以使用the RGB+alpha constructor创建Color,然后使用getAlpha()方法获取Alpha值。

现在,以下代码适用于我:

public static BufferedImage trimHorizontally(BufferedImage img) {
    int width = img.getWidth(), height = img.getHeight();
    int x0, x1;
    int j, i;
    int alpha;

    leftLoop:
        for(i = 0; i < width; i++) {

            for(j = 0; j < height; j++) {
                if(new Color(img.getRGB(i, j), true).getAlpha() != 0)  {
                    break leftLoop;
                }
            }
        }
    x0 = i;
    rightLoop:
        for(i = width-1; i >= 0; i--) {

            for(j = 0; j < height; j++) {
                if(new Color(img.getRGB(i, j), true).getAlpha() != 0) {
                    break rightLoop;
                }
            }
        }
    x1 = i+1;

    return img.getSubimage(x0, 0, x1-x0, height);
}

注意:

img必须是TYPE_INT_ARGB类型,或其他类型,以便在getRGB()数据的最后一个字节中保留其alpha值(如果您不知道这意味着什么,只要尝试上面的代码,如果它不起作用covert to ARGB。)

另请确保使用image format that supports transparency JPG)。