0

I have an array int[] shadesOfGray size n*n containing values from [0,255]. Is it possible to create 8-bit grayscale bitmap from this array?

E.g, if int[] shadesOfGray = {255, 255, 255, 128, 128, 128, 0, 0, 0}

then the intensity of the corresponding pixels in bitmap would be:

255 255 255
128 128 128
0    0   0 

I have tried something like this:

   private static void generateBMPwithDistribution(int[] shadesOfGray, int sum, String path) throws IOException {

        int dim = 100;  
        byte[] buffer = new byte[dim * dim];    

        for (int x = 0, i = 0; x < dim; x++)        
            for (int y = 0; y < dim; y++)                                              
                buffer[(x * dim) + y] = (byte) (shadesOfGray[i]); // problem  

        try {
            ImageIO.write(getGrayscale(dim, buffer), "bmp", new File(path));
        } catch (IOException e) {
            ...
        }

    }

    public static BufferedImage getGrayscale(int width, byte[] buffer) {
        int height = buffer.length / width;
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        int[] nBits = { 8 };
        ColorModel cm = new ComponentColorModel(cs, nBits, false, true,
                Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
        SampleModel sm = cm.createCompatibleSampleModel(width, height);
        DataBufferByte db = new DataBufferByte(buffer, buffer.length);
        WritableRaster raster = Raster.createWritableRaster(sm, db, null);
        BufferedImage result = new BufferedImage(cm, raster, false, null);

        return result;
    }

Since I want 8-bit .bmp, I am copying values in buffer and then writing buffer into file. Problem is for values >= 128; byte is considered to have negative value. Is there a way in Java to get over this?

concrete_rose
  • 198
  • 3
  • 15
  • http://stackoverflow.com/questions/9609394/java-byte-array-contains-negative-numbers – Piglet May 21 '16 at 13:44
  • Thank you, but the problem remains; When I want to print pixels with, e.g, value of intensity 128, that value gets interpreted as -128 and it is OK. It is grey. But, afterwards, I read the image again, and this pixel has value 188, not 128. This is why I am confused. – concrete_rose May 21 '16 at 14:59
  • you need to use RGB - any other model will probably distort the values - and where did you get that convoluted scheme in getGrayscale ?? – gpasch May 21 '16 at 16:00
  • It's code I've found somewhere around... :) I have grayscale histogram (256 shades of grey) and I have to generate greyscale image that has the same histogram. That's why I am not certain how to switch from grayscale to rgb and is it even possible... – concrete_rose May 21 '16 at 16:30
  • Thank you, you were absolutely right. I have manually made bitmap with RGB values, where both red = green = blue = desired grey shade. Everything else distorts values, as you said. Thank you once more! – concrete_rose May 21 '16 at 18:49
  • your solution helped me to convert a byte[] array to grayscale image without distorting the grayscale values via the default colormodel/colorspace. thanks!!! – datahaki Dec 30 '18 at 15:58

1 Answers1

0

Your procedure can look something like this:

private static void generateBMPwithDistribution(int[] shadesOfGray, int sum, String path) throws IOException {

    int dim1 = (int)Math.sqrt(shadesOfGray.length), dim=100*dim1;
    int[] buffer = new int[dim * dim];    

    int howManyTimes=dim/dim1;
    for (int x = 0; x < dim; x++)        
        for (int y = 0; y < dim; y++) {                                             
            int valueToReplicate=shadesOfGray[(x + y*dim)/howManyTimes];
            buffer[x + y*dim] = 0xff000000|(valueToReplicate<<16)|(valueToReplicate<<8)|valueToReplicate;
        }

    BufferedImage result=new BufferedImage(dim, dim, BufferedImage.TYPE_INT_RGB);

    try {
        ImageIO.write(result, "bmp", new File(path));
    } catch (IOException e) {
        ...
    }

}
gpasch
  • 2,672
  • 3
  • 10
  • 12