0

Currently I am trying to send a BufferedImage in Java. I am aware that BufferedImage isn't serialize, so I tried to create a serializable version. Here is the code to that: import java.awt.image.BufferedImage;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javax.imageio.ImageIO;

public class SerializableBufferedImage implements Serializable{

    private long id;
    private String name;
    private BufferedImage image;

    public SerializableBufferedImage(long id, String name, BufferedImage image){

        this.id = id;
        this.name = name;
        this.image = image;

    }

    public long getId(){return id;}   
    public void setId(long id){this.id = id;}

    public String getName(){return name;}
    public void setName(String name){this.name = name;}

    public BufferedImage getImage(){return image;}
    public void setImage(BufferedImage image){this.image = image;}

    public void writeObject(ObjectOutputStream out){

        try{
            out.writeObject(name);
            ImageIO.write(image, "jpeg", ImageIO.createImageOutputStream(out));

        }catch(IOException ioException){

            ioException.printStackTrace();

        }

    }

    public void readObject(ObjectInputStream in){

        try{

            name = (String) in.readObject();
            image = ImageIO.read(ImageIO.createImageInputStream(in));

        }catch(IOException ioException){

            ioException.printStackTrace();

        }catch(ClassNotFoundException classNotFoundException){

            classNotFoundException.printStackTrace();

        }

    }

}

This is what I do when I try to send an image:

private void sendImage(BufferedImage image){    

    SerializableBufferedImage test = new SerializableBufferedImage(1, "test", image);

    try{
        if(output == null){

            showMessage("MAKE SURE THAT YOU ARE CONNECTED TO SOMEONE!\n");

        }

        else{

            if(image == null)System.out.println("image is null in sendImage");

            output.writeObject("CODE - 4");
            output.flush();
            System.out.println("here");
            test.writeObject(output);
            System.out.println("done");
            output.flush();
            System.out.println("Just sent code " + 4);

        }

    }catch(IOException ioException){

        System.out.println("\nERROR! UNABLE TO SEND IMAGE CODE!");
        ioException.printStackTrace();

    }

}

The program will crash whenever I try to send an image via this method. Am I not understanding what serialization is, is it implemented wrong, am I using it wrong, or is it some other problem. The output for the code can be found here: http://pastebin.com/0n4yS2ap.

dsiegler19
  • 369
  • 1
  • 5
  • 20
  • Images are usually transferred using common formats such as GIF, PNG, etc. There is no need for a `BufferedImage` to be serializable - you can always use `ImageIO` to read or write an image in a well-known format. – RealSkeptic Mar 19 '16 at 22:04
  • Well, that is what his code is trying to do; so I am wondering: what is the point of your comment? – GhostCat Mar 19 '16 at 22:05
  • In your SerializableBufferedImage class, your BufferedImage field, image, should be marked **transient**. This is key, otherwise the SerializableBufferedImage will still try to serialize the field when it itself is serialized. – Hovercraft Full Of Eels Mar 19 '16 at 22:06
  • Also, don't write out the image in a lossy manner. Better to write it as a lossless png image format. – Hovercraft Full Of Eels Mar 19 '16 at 22:07
  • e.g., `private transient BufferedImage image;` – Hovercraft Full Of Eels Mar 19 '16 at 22:08
  • Do read and write Object have to be private? – dsiegler19 Mar 19 '16 at 22:09
  • I think that they should be. Also don't you need default methods as well? – Hovercraft Full Of Eels Mar 19 '16 at 22:10
  • What do you mean by that (the default methods that is)? Also, then would I have to move the read and writeObject to Server because they have to be private? – dsiegler19 Mar 19 '16 at 22:12
  • Did you read the [Serializable API](http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html)? **THOSE** default methods. – Hovercraft Full Of Eels Mar 19 '16 at 22:13
  • Oh of course. It's an interface. I'm stupid. – dsiegler19 Mar 19 '16 at 22:14
  • Well, no, it defines no methods per se, but it does mention "special handling" methods that are available for use. – Hovercraft Full Of Eels Mar 19 '16 at 22:16
  • 1
    I put that down as an answer; but that was wrong. So, by default, such read/write method should be private, not public. The point is that the JVM will search for them, and can invoke them; although they are private. But of course, they are also called when the methods are public. But: when they are public, you inherit them. And the idea of this (de)serialization "overrides" is that you **do not want** that stuff to be passed down to child classes. That allows you to have to implement them for base/derived classes; and stuff still works. – GhostCat Mar 19 '16 at 22:26
  • 1
    Anything with writing the image through `ImageIO.write` to a `ByteArrayOutputStream` and reading it back via a `ByteArrayInputStream` and then through `ImageIO.read` ...? – MadProgrammer Mar 19 '16 at 22:27
  • @MadProgrammer Can you please elaborate because when I read this it makes absolutely no sense. Sorry if I'm not seeing something. – dsiegler19 Mar 19 '16 at 22:36
  • 1
    Look, I just have a personal dislike of serialisation for a number of reasons, so when ever I see people trying to use it, I like to encourage other solutions. You could, for example, use ImageIO.write to write the BufferedImage into a ByteArrayOutputStream and the write the result of that out through your socket or what ever InputStream you're writing to, you could then read it into a ByteArrayInputStream and the read that via ImageIO.read back to BufferedImage. I do this when working with sockets as ImageIO does some funky things with the streams – MadProgrammer Mar 19 '16 at 22:44
  • Okay I'll try that now. – dsiegler19 Mar 19 '16 at 22:47
  • It worked. Thanks a lot. – dsiegler19 Mar 19 '16 at 22:54

0 Answers0