2013-02-25 7 views
12

私はjavaで単純な画像編集プログラムを作成しようとしています。編集中の画像に関するすべての情報を持つImageCanvasオブジェクトを作成しました(基本プロパティ、適用されるエフェクトのリスト、BufferedImageレイヤのリストなど)後で再び開くことができた。BufferedImagesを含むオブジェクトをシリアライズする方法

私は、Javaのdefualt Serializableインターフェイスを使って、探していたものと同じものがあると思っていました。オブジェクト全体をファイルに書き込んで、後で再びメモリに読み込むことができました。ただし、ImageCanvasにはArrayList<BufferedImage>が含まれ、BufferedImageにはシリアライズ可能ではありません(それ以外はすべてです)。

は、私はwriteObject()readObject()メソッドをオーバーライドすることが可能である知っているが、私はそうしたことがないとBufferedImageを読み出し/書き込みするためにいくつかのカスタム方法を、Javaが他のすべてシリアライズ持ち、持っている任意の簡単な方法がある場合は、私が思っていましたディスクに?または、私が見落としているディスクにImageCanvasオブジェクト全体を簡単に書き込むための他の方法がありますか?最終的に私は独自のカスタムイメージファイルタイプを実装するかもしれませんが、今はテスト中にファイルを一時的に保存するための素早く簡単な方法が必要でした(ImageCanvasクラスが大きく変わるので更新したくありません私の最終的なファイルタイプは完成前です)。

答えて

23

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)); 
     } 
    } 
} 
+0

どうすれば使えますか?メソッドはプライベートです。 – avicennasoftwarelabs

+1

@avicennasoftwarelabs writeObjectとreadObjectを実装するだけで、メソッドがプライベートであっても、オブジェクトをシリアライズ/デシリアライズするときにこれらのメソッドを使用するようにJavaシリアル化が指示されます。 –

+2

残念ながら、ImageIOのPNGデコーダにはバグがあります。つまり、読み込んだデータが書き込んだデータと同じではない(色が1つずれていることが多い) – mjaggard

0

シリアル化は、静的なデータを維持するという点でかなり簡単です。 そうでない場合は、Serializationファミリのメソッドの読み込み/書き込みオブジェクトで適切な場所にあります。 「BufferedImage」が何であるか考えてみてください。 バッファリングされたストリーミング実装です。 シリアル化するには、データをbyte []配列のような静的オブジェクトに書き出す必要があります。その後、バッファリングされたストリーミングがそのバイト[/]に出入りするようにTHATオブジェクトを直列化/逆直列化してBufferedImageに/アレイ。

+0

あなたは(どのように[]バイトにBufferedImageを回すか、どのようにあなたがImageCanvasのシリアライゼーションの残りの部分とすることをを組み込むん)これは実際に私の状況で行われるだろうか示すためにいくつかのコードを提供してもらえますか? – scaevity

+0

コンストラクタに関連するBufferedImage(このクラスを使用する必要がある場合)のメソッドに従います。これにより、WritableRaster(およびその他のデータ)を使用してBufferedImageを作成できます。 BufferedImageには、WritableRasterを返すgetWritableTile(x、y)メソッドがあります。 WritableRasterが継承するRasterクラスには、たとえばプリミティブint []の配列を返すことのできるさまざまなgetPixel()メソッドがあります。それは非常に単純ではありませんが、プリミティブからBufferedImageに戻るために逆にすることができます。また、シリアライズ/デシリアライズが容易な別のベースイメージクラスの使用を検討してください。 –

関連する問題