拜托,请有人在下面向我解释。它让我疯狂。我正在玩java中的数组创建8位灰度图像。
下面的代码应该生成黑色>白色水平渐变。第1部分和第2部分确实产生了所需的图像,但在 1 中传递给getimageFromarray
的int []从-128到127,而 2 从0到255,但它们产生相同的图像。 3 会产生我希望 1 生成的(不需要的)图像,单独使用其最大值和最小值。
这是为什么?怎么会这样?
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Test {
final static int WIDTH = 320;
final static int HEIGHT = 256;
// Black and white as int
final static int BLACK = 0;
final static int WHITE = 255;
//...same, but not
final static int BLACK_WRONG = 127;
final static int WHITE_WRONG = -128;
// Black and white as byte val
final static byte BLACK_BYTE = -0x80; //i.e -128
final static byte WHITE_BYTE = 0x7f; // i.e. 127
public static void main(String[] args) throws IOException {
int[] pixels = new int[WIDTH*HEIGHT];
int[] m;
// Generates gradient1.bmp
// produces as expected - black at top, white at bottom
int numb=0,c=0;
byte grey1 = BLACK;
while (numb<pixels.length){
// inc through greyscales down image
if (c>WIDTH){
grey1++;
c=0;
}
// cast from byte to int
pixels[numb] = grey1;
// inc column and count
c++;
numb++;
}
m = getMaxMin(pixels); // max 127 , min -128
System.out.printf("Maxmin %s; %s;\n",m[0], m[1]);
getImageFromArray("gradient1.bmp", pixels,WIDTH, HEIGHT);
//*************************************************************************
// Generates gradient3.bmp
// produces as expected - black at top, white at bottom
numb=0;
c=0;
int grey2 = BLACK; //i.e zero
while (numb<pixels.length){
// inc through greyscales down image
if (c>WIDTH){
grey2++;
c=0;
}
// no cast
pixels[numb] = grey2;
// inc column and count
c++;
numb++;
}
m = getMaxMin(pixels); // max 255, min 0
System.out.printf("Maxmin %s; %s;\n",m[0], m[1]);
getImageFromArray("gradient2.bmp", pixels,WIDTH, HEIGHT);
//*************************************************************************
// Generates gradient3.bmp
// produces as unexpected - midgrey > white. black > midgrey
numb=0;
c=0;
byte grey3 = BLACK_BYTE; //i.e zero
while (numb<pixels.length){
// inc through greyscales down image
if (c>WIDTH){
grey3++;
c=0;
}
// no cast
pixels[numb] = grey3;
// inc column and count
c++;
numb++;
}
m = getMaxMin(pixels); // max 127 , min -128
System.out.printf("Maxmin %s; %s;\n",m[0], m[1]);
getImageFromArray("gradient3.bmp", pixels,WIDTH, HEIGHT);
}
//*******************************************************************************
static int sWidth,sHeight = 0;
static BufferedImage sImage = null;
static WritableRaster sRaster=null;
public static BufferedImage getImageFromArray(String filename, int pixels[], int width, int height) throws IOException {
if (sImage == null){
sImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
sRaster = sImage.getRaster();
}
sRaster.setPixels(0,0,width,height,pixels);
try {
ImageIO.write(sImage, "bmp", new FileOutputStream(filename));
} catch (IOException e) {
e.printStackTrace();
}
return sImage;
}
static int[] getMaxMin(int[] v){
int max=0,min=0;
for (int i:v){
if (i>max) max = i;
if (i<min) min = i;
}
int[] r = {max,min};
return r;
}
}
答案 0 :(得分:1)
假设BufferedImage
将RGBA(或类似的)编码颜色作为输入,您需要从各自的RGBA组件正确构造int
。
要转换灰色的带符号字节R = 0
,G = 0
,B = 0
,A = 127
,您需要将它们转换为无符号{ {1}}并将它们组合成一个int
,如下所示:
int
这与分配 7f 7f 7f ff 的十六进制值相同。
int color = (((A & 0xff) << 24 | ((B & 0xff) << 16) | ((G << 8) | (R & 0xff));
掩码是将签名字节(-128到127)正确转换为无符号整数(0到255)所必需的。
& 0xff
'左移“int内的字节。
您可能需要更改RGBA的输入顺序才能获得正确的结果。