0

请,请有人可以在下面向我解释。它让我发疯。我正在玩从 java 中的数组创建 8 位灰度图像。

下面的代码应该产生黑色 > 白色水平渐变。第 1 部分和第 2 部分确实产生了所需的图像,但在 int[] 中传递给getimageFromarrayin 1从 -128 到 127,并且 in 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;
    }
}
4

1 回答 1

1

假设BufferedImage将 RGBA(或类似的)编码颜色作为输入,您需要int从它们各自的 RGBA 组件中正确构造这些 s。

要将带符号的 bytes R = 0, G = 0, B = 0,转换A = 127GREY,您必须将它们转换为 unsigned ints 并将它们组合成一个int,如下所示:

int color = (((A & 0xff) << 24 | ((B & 0xff) << 16) | ((G << 8) | (R & 0xff));

这与分配7f 7f 7f ff的十六进制值相同。& 0xff掩码对于正确地将有符号字节(-128 到 127)转换为无符号整数(0 到 255)是必要的。

<<'左移' int 内的字节。

您可能必须更改 RGBA 的输入顺序才能获得正确的结果。

于 2013-04-18T06:44:58.793 回答