Java — отправка объекта, который указывает на BufferedImage через сокет

Я и группа друзей работаем над проектом на Java, и нам нужна помощь в отправке объектов через сокеты.

До сих пор мы добились отправки простых объектов (целых, строк и прочего) через сокеты, используя ObjectOutputStream и ObjectInputStream. Однако сегодня мы столкнулись с огромной проблемой (во всяком случае, для нас огромной ^^)

У нас есть древовидная структура, которую нам нужно отправить с одного ПК на другой. Проблема в том, что в каждом узле этого дерева у нас есть ссылка на BufferedImage, и его нельзя сериализовать.

Сегодня мы много исследовали и обнаружили, что можем использовать ImageIO.write() для отправки одного BufferedImage через OutputStream сокета, однако для нас это бесполезно, так как нам не нужно отправлять BufferedImage сам по себе, а целое дерево, где он находится.

Что нам нужно, так это способ (если он существует) сериализовать каждый BufferedImage, преобразовать его в другой класс, если это необходимо, при создании дерева и иметь каждый узел дерева вместо ссылки на этот новый сериализуемый класс, чтобы дерево можно было отправить как целый объект...

Мы действительно не заботимся о производительности, поскольку деревья, которые мы отправляем, не такие уж большие (максимум 10-15 узлов). Заранее спасибо за помощь, извините за паршивый английский. О, и это для... ну, своего рода домашнее задание, если вы хотите иметь это в виду :-)

Спасибо!!


person dhcarmona    schedule 07.11.2011    source источник


Ответы (3)


на каждом узле вы можете использовать writeObject() и readObject(), проверяя http://java.sun.com/developer/technicalArticles/Programming/serialization/ для получения дополнительной информации.

по сути это станет

public Node implements Serializable{

    transient BufferedImage buff;//transient make it so it won't be written with defaultWriteObject (which would error)

    private void writeObject(ObjectOutputStream out)throws IOException{
        out.defaultWriteObject();
        //write buff with imageIO to out
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        in.defaultReadObject();
        //read buff with imageIO from in
    }
}
person ratchet freak    schedule 07.11.2011
comment
Ладно, дай мне посмотреть, получу ли я это. Основываясь на чтении ссылки, которую вы мне дали, эти методы будут вызываться каждый раз, когда протокол сериализации касается узла, либо для чтения из сокета (он вызовет readObject), либо для записи в сокет (он вызовет writeObject) . Итак, я должен использовать эти методы, чтобы записать BufferedImage в ObjectOutputStream, а затем отправить его через сокет, вызвав его метод defaultWriteObject() ??? Пожалуйста, дайте мне знать, если я правильно понял ^^ - person dhcarmona; 07.11.2011
comment
запись в out отправит его через сокет, лучше сначала вызвать чтение/запись по умолчанию, а затем прочитать или записать BufferedImage, который вы можете проверить docjar.com/html/api/java/util/HashMap.java.html внизу для реального примера использования - person ratchet freak; 07.11.2011
comment
Работал как шарм!! Спасибо большое!! - person dhcarmona; 07.11.2011

Вы можете преобразовать BufferedImage в массив байтов на стороне клиента и отправить его как обычный массив байтов, а на стороне сервера создать BufferedImage из этого массива байтов. Ниже приведен код для преобразования BufferedImage в массив байтов и наоборот.

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;

public class ImageTest {

public static void main(String[] args) {

    try {

        byte[] imageInByte;
        BufferedImage originalImage = ImageIO.read(new File(
                "c:/darksouls.jpg"));

        // convert BufferedImage to byte array
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(originalImage, "jpg", baos);
        baos.flush();
        imageInByte = baos.toByteArray();
        baos.close();

        // convert byte array back to BufferedImage
        InputStream in = new ByteArrayInputStream(imageInByte);
        BufferedImage bImageFromConvert = ImageIO.read(in);

        ImageIO.write(bImageFromConvert, "jpg", new File(
                "c:/new-darksouls.jpg"));

    } catch (IOException e) {
        System.out.println(e.getMessage());
    }
}
}
person kaysush    schedule 15.06.2012

Если вы хотите использовать потоки объектов, вы можете обернуть буферизованное изображение внутри класса, который реализует Serializable и имеет атрибут, представляющий собой массив байтов (данные изображения в виде массива байтов). Вам придется изменить свой код, изменив ссылки BufferedImage на SerializableImage (пример имени класса).

Если вы это сделаете, ваш класс будет сериализован и передан.

person Felipe Cruz    schedule 07.11.2011