Java.awt.Image を BufferedImage や Byte 配列に変換する方法
java.awt.Image を BufferedImage や byte 配列に変換する方法
Java ImageIO で Flickr 並みのサムネイル画像をつくるという記事で、
java.awt.Image を BufferedImage や byte 配列に変換する方法は次回。
と書いたにも関わらず、そのまま放置になっていた(コメントで指摘されているのに気づいたのも今日だ。すまん)。
概要
まずは java.awt.image.BufferedImage を byte 配列に変換する方法を紹介する。
そのあと、java.awt.Image を java.awt.image.BufferedImage に変換する方法を紹介するので、このふたつを組み合わせれば、
Image --> BufferedImage --> byte[]
が実現できるわけだ。
BufferedImage を byte[] に変換する
BufferedImage から byte 配列の変換は、javax.imageio.ImageWriter でわりかし素直に実装できる。
MicrosoftのFrontPage 2003でホームページを作る方法BufferedImage image = ...; ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); ImageWriter writer = ImageIOKit.getImageWritersByFormatName(formatName); ImageOutputStream stream = ImageIO.createImageOutputStream(bytesOut); try { writer.setOutput(stream); writer.write(image); stream.flush(); } finally { writer.dispose(); if (stream != null) try { stream.どのように私はPICのURLを取得するにはclose(); } catch (Throwable t) {;} } byte[] bytes = bytesOut.toByteArray(); ...
ImageWriteParam も組み合わせれば、圧縮率などの設定ができる。
Image を BufferedImage をに変換する
一筋縄ではいかないのが、Image を BufferedImage をに変換する方法だ。
以下では、image 変数が java.awt.Image のインスタンスであるとして、順を追って説明する。
まず、image が BufferedImage のインスタンスなら、以降は何もする必要がない。
if (image instanceof BufferedImage) { ... }
次に、java.awt.Image のインスタンスは、実際のデータが非同期でロードされているかもしれないので、変換処理を行う前に、java.awt.MediaTracker でロードが完了するまで待機する。
誰がアニメーター開始// java.awt.MediaTracker でロードを待機 MediaTracker tracker = new MediaTracker(new Component(){}); tracker.addImage(image, 0); tracker.waitForAll();
ここからが実際の変換処理になるが、基本的に、
- 新規に BufferedImage を生成
- 生成した BufferedImage に Image のピクセルをコピー
という処理になる。
PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, -1, -1, false); pixelGrabber.grabPixels(); ColorModel cm = pixelGrabber.getColorModel(); final int w = pixelGrabber.getWidth(); final int h = pixelGrabber.getHeight(); WritableRaster raster = cm.createCompatibleWritableRaster(w, h); BufferedImage renderedImage = new BufferedImage( cm, raster, cm.isAlphaPremultiplied(), new Hashtable()); renderedImage.getRaster().setDataElements(0, 0, w, h, pixelGrabber.getPixels());
上記のコードでは、元の ColorModel もサポートするために、PixelGrabber を使っている。
あとは、ここで生成した BufferedImage を byte 配列に変換してやればよい。
0 コメント:
コメントを投稿