2

As the title suggests, I'm attempting to write a byte array to a bmp file in Java. Currently, my program successfully writes data to the file location, however it appears to be missing data and cannot be opened because of it. Of the two functions listed below the goal is:

fromImage takes a grayscale bmp image byte data and converts each integer to a binary string, which is then stored in a LinkedList node. toImage takes that LinkedList, converts the binary strings back to integers and then writes the new byte array back to another file.

public static LinkedList<String> fromImage(BufferedImage img) {
    LinkedList<String> new_buff = new LinkedList<String>();
    //try{
        //img = ImageIO.read(new File("img/lena.bmp"));
        byte[] byte_buffer = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();

        for(byte b : byte_buffer){
            String buffer;
            buffer = Integer.toBinaryString(b & 255 | 256).substring(1);
            new_buff.addLast(buffer);
            //System.out.println(buffer);
        }
    //}catch(IOException e){}
    System.out.println("Exiting fromImage");
    return new_buff;
}

// Save a binary number as a BMP image
// Image input hardcoded atm
public static BufferedImage toImage(LinkedList<String> bi) {
    BufferedImage img = null;
    int b;
    byte[] bytes = new byte[bi.size()];
    for(int i = 0; i < bi.size(); i++){
        String temp = bi.get(i);
        b = Integer.parseInt(temp);
        bytes[i] = (byte) b;
        //System.out.println(i);
    }
    System.out.println("Exiting For loop");
    try{
        Files.write(Paths.get("img/encrypted.bmp"), bytes);
        //img = ImageIO.read(new File("img/lena.bmp"));
        //ImageIO.write(img, "bmp", new File("img/encrypted.bmp"));
        //img = ImageIO.read(new File("img/encrypted.bmp"));
    }catch(IOException e){}
    System.out.println("Exiting toImage");
    return img;
}

So ultimately, my question is - Where is the data I'm missing, why am I missing it, and what can I do to fix it?

2
  • What is this conversion via LinkedList<String> about? Can you unit-test that this really works (i.e. can round-trip a byte[] properly)? Commented Apr 27, 2015 at 1:38
  • I'm not 100% sure I understand what you're asking, but the reason I'm storing it as a LinkedList<String> is because the pixel bytes pulled from the original image are integers and I need to do least significant bit changes on binary numbers. Commented Apr 27, 2015 at 1:44

2 Answers 2

4

BMP has a file structure.

Here, you are writing to a file named "encrypted.bmp", so I suppose your bytes are the encryption of something, and thus do not represent a valid bmp file.

You will have to comply to the BMP file structure, adding a header and footer so that your bytes are eg. the pixel part of the BMP file.

The easiest way to do that is by writing your image to a BufferedImage img and then use ImageIO.write(img, "BMP", new File("encrypted.bmp")).

Sign up to request clarification or add additional context in comments.

3 Comments

Alright. That's what a friend suggested. Do you have a suggestion for where I can learn how to add the missing header/footer information? Currently, there is no encrypted information.The encryption will be a least significant bit change on the pixel binary data, however I have not yet implemented that portion.
The wikipedia link has the complete file structure, so you could use it to write your bitmaps. Otherwise, this site seems to be pretty clear about how to use the BMP file format. And if you don't want to reinvent the wheel, just use ImageIO.write(img, "BMP", new File("encrypted.bmp")) where img is a BufferedImage with your pixel values.
I was using ImageIO previously and was having trouble, however it looks like I might have been using it incorrectly now that I am looking over it again. Thank you for the help.
1

I just want to turn Ekleog's answer into a usable code:

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
public static boolean arrayToBMP(byte[] pixelData, int width, int height, File outputFile) throws IOException {
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    img.setData(Raster.createRaster(img.getSampleModel(), new DataBufferByte(pixelData, pixelData.length), null));
    return javax.imageio.ImageIO.write(img, "bmp", outputFile);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.