我正在尝试创建一个仅从右侧和左侧裁剪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
....
答案 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)。