Как сериализовать объект, который включает BufferedImages

Я пытаюсь создать простую программу для редактирования изображений в java. Я создал объект ImageCanvas, который имеет всю информацию об редактируемом изображении (некоторые базовые свойства, список применяемых эффектов, список слоев BufferedImage и т.д.), И я хотел бы простой способ его сохранения на диск, чтобы его можно было открыть позже.

Я понял, что использование интерфейса Java defualt Serializable может быть именно тем, что я искал, и я мог бы просто написать весь объект в файл и снова прочитать его обратно в память позже. Однако ImageCanvas включает ArrayList<BufferedImage>, а BufferedImage не является сериализуемым (все остальное).

Я знаю, что можно переопределить методы writeObject() и readObject(), но я никогда не делал этого, и мне было интересно, есть ли простой способ заставить Java сериализовать все остальное и иметь собственный способ чтения/пишите BufferedImage на диск? Или есть другой способ легко написать весь объект ImageCanvas на диск, который я пропускаю? В конце концов я мог бы реализовать свой собственный тип файла изображения, но сейчас я хотел бы быстро и просто временно сохранить файлы во время тестирования (класс ImageCanvas сильно изменится, поэтому я не хотел, чтобы продолжайте обновлять свой собственный тип файла, прежде чем я его окончательно доработаю).

Ответ 1

сделать ваш ArrayList<BufferedImage> переходным процессом и реализовать собственный метод writeObject(). В этом случае напишите регулярные данные для вашего ImageCanvas, затем вручную выпишите данные байта для изображений, используя формат PNG.

class ImageCanvas implements Serializable {
    transient List<BufferedImage> images;

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(images.size()); // how many images are serialized?
        for (BufferedImage eachImage : images) {
            ImageIO.write(eachImage, "png", out); // png is lossless
        }
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        final int imageCount = in.readInt();
        images = new ArrayList<BufferedImage>(imageCount);
        for (int i=0; i<imageCount; i++) {
            images.add(ImageIO.read(in));
        }
    }
}

Ответ 2

Сериализация довольно прямолинейна, поскольку она сохраняет статические данные. В противном случае вы будете в нужном месте с объектом чтения/записи в семействе методов Serialization. Подумайте, что такое "BufferedImage". Это буферизованная потоковая реализация. Для сериализации данные должны быть сброшены на статический объект, такой как массив byte [], а затем объект THAT может быть сериализован/десериализован в/из BufferedImage, так что буферизованная потоковая передача теперь входит в/из этого массива byte [].