Как сериализовать и отправить BufferedImage

В настоящее время я пытаюсь отправить BufferedImage в Java. Я знаю, что BufferedImage не сериализуется, поэтому я попытался создать сериализуемую версию. Вот код для этого: 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();

        }

    }

}

Вот что я делаю, когда пытаюсь отправить изображение:

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();

    }

}

Программа будет аварийно завершать работу всякий раз, когда я пытаюсь отправить изображение с помощью этого метода. Я не понимаю, что такое сериализация, неправильно ли она реализована, неправильно ли я ее использую или это какая-то другая проблема. Результат кода можно найти здесь: http://pastebin.com/0n4yS2ap.


person dsiegler19    schedule 19.03.2016    source источник
comment
Изображения обычно передаются с использованием распространенных форматов, таких как GIF, PNG и т. д. Нет необходимости в сериализации BufferedImage — вы всегда можете использовать ImageIO для чтения или записи изображения в общеизвестном формате.   -  person RealSkeptic    schedule 20.03.2016
comment
Ну, это то, что пытается сделать его код; поэтому мне интересно: в чем смысл вашего комментария?   -  person GhostCat    schedule 20.03.2016
comment
В вашем классе SerializableBufferedImage ваше поле BufferedImage, image, должно быть помечено как transient. Это ключ, иначе SerializableBufferedImage все равно попытается сериализовать поле, когда оно само будет сериализовано.   -  person Hovercraft Full Of Eels    schedule 20.03.2016
comment
Кроме того, не записывайте изображение с потерями. Лучше писать в формате png без потерь.   -  person Hovercraft Full Of Eels    schedule 20.03.2016
comment
Должен ли объект чтения и записи быть закрытым?   -  person dsiegler19    schedule 20.03.2016
comment
Я думаю, что они должны быть. Также вам не нужны методы по умолчанию?   -  person Hovercraft Full Of Eels    schedule 20.03.2016
comment
Что вы подразумеваете под этим (методы по умолчанию)? Кроме того, тогда мне придется перемещать объекты чтения и записи на сервер, потому что они должны быть частными?   -  person dsiegler19    schedule 20.03.2016
comment
Вы читали Serializable API? ЭТИ методы по умолчанию.   -  person Hovercraft Full Of Eels    schedule 20.03.2016
comment
О Конечно. Это интерфейс. Я тупой.   -  person dsiegler19    schedule 20.03.2016
comment
Ну, нет, в нем не определены методы как таковые, но упоминаются специальные методы обработки, доступные для использования.   -  person Hovercraft Full Of Eels    schedule 20.03.2016
comment
Я записал это как ответ; но это было неправильно. Таким образом, по умолчанию такой метод чтения/записи должен быть закрытым, а не общедоступным. Дело в том, что JVM будет их искать и может их вызывать; хотя они частные. Но, конечно, они также вызываются, когда методы общедоступны. Но: когда они общедоступны, вы их наследуете. И идея переопределения (де)сериализации заключается в том, что вы не хотите передавать этот материал в дочерние классы. Это позволяет вам реализовать их для базовых/производных классов; и все еще работает.   -  person GhostCat    schedule 20.03.2016
comment
Что-нибудь с записью изображения через ImageIO.write в ByteArrayOutputStream и чтением его обратно через ByteArrayInputStream, а затем через ImageIO.read ...?   -  person MadProgrammer    schedule 20.03.2016
comment
@MadProgrammer Не могли бы вы уточнить, потому что, когда я это читаю, это не имеет абсолютно никакого смысла. Извините, если я чего-то не вижу.   -  person dsiegler19    schedule 20.03.2016
comment
Послушайте, у меня просто личная неприязнь к сериализации по ряду причин, поэтому, когда я вижу людей, пытающихся ее использовать, мне нравится поощрять другие решения. Вы можете, например, использовать ImageIO.write для записи BufferedImage в ByteArrayOutputStream и записи результата этого через ваш сокет или какой-либо InputStream, в который вы пишете, вы можете затем прочитать его в ByteArrayInputStream и прочитать, что через ImageIO.read обратно в BufferedImage. Я делаю это при работе с сокетами, так как ImageIO делает некоторые странные вещи с потоками.   -  person MadProgrammer    schedule 20.03.2016
comment
Хорошо, сейчас попробую.   -  person dsiegler19    schedule 20.03.2016
comment
Это сработало. Большое спасибо.   -  person dsiegler19    schedule 20.03.2016