画像をBufferedImageに変換するJava


83

StackOverflowにはこのリンクのような質問がすでにあり、受け入れられた答えは「キャスト」です。

Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;

私のプログラムでは、次のことを試します。

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = (BufferedImage) image;

残念ながら、実行時エラーが発生します。

sun.awt.image.ToolkitImageをjava.awt.image.BufferedImageにキャストすることはできません

明らかにキャストは機能しません。
質問は:ImageをBufferedImageに変換する適切な方法は何ですか(またはありますか)?


あなたがバッファリングされた画像を拡大縮小したい場合は、これがこの[しようと試みるstackoverflow.com/questions/4216123/... [1]:stackoverflow.com/questions/4216123/...を
user902383

7
ちなみに、それを言っているのはコンパイラではありません。実際には、コンパイルエラーではなくランタイムエラーが発生しています。
スティーブンC

1
あなたが正しいです。これを指摘してくれてありがとう。それに応じて質問を編集します。
アレックウィルク2012

@ user902383彼らが私の質問に直接答えていなくても、それらは素晴らしい解決策でもあります。
アレックウィルク2012

OPへの小さなこと:メソッドImageIO.read(File)BufferedImageそのシグネチャによってaを返します。(参照)最初にImage変数に割り当ててから、型にキャストする必要はありませんBufferedImage。それはあなたのコードを読んでいる人々を混乱させるかもしれません。
kevinarpe 2013

回答:


124

Javaのゲームエンジン

/**
 * Converts a given Image into a BufferedImage
 *
 * @param img The Image to be converted
 * @return The converted BufferedImage
 */
public static BufferedImage toBufferedImage(Image img)
{
    if (img instanceof BufferedImage)
    {
        return (BufferedImage) img;
    }

    // Create a buffered image with transparency
    BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

    // Draw the image on to the buffered image
    Graphics2D bGr = bimage.createGraphics();
    bGr.drawImage(img, 0, 0, null);
    bGr.dispose();

    // Return the buffered image
    return bimage;
}

7
@SriHarshaChilakapati You shouldn't be worrying about the memory when using Java.Javaアプリケーションによる平均メモリ消費量から判断すると、他の開発者は間違いなくメモリについて少し心配する必要はありません。
トマシュザト-モニカを復活させる2015年

1
@TomášZatoあなたはC ++の世界から来たようで、画像データのピクセルのメモリを再利用しようと考えていました。以前のコメントでは、この場合、GCがJavaでメモリを処理するため、メモリについて心配する必要はありません。
Sri Harsha Chilakapati 2015年

2
@SriHarshaChilakapatiでは、ガベージコレクターはリソースを消費しませんか?GCは、メモリを取り巻くコードからあなたを救うだけです。ハードウェアの制限をなくすことはありません。
Andrew Sannier 2015

5
これがあれば動作しませんImageから、まだロードされていないgetWidth(null)getHeight(null)を返します-1場合には
DIMS

1
BufferedImage.TYPE_INT_RGBサムネイルの色を正しくするために、ARGBの代わりに使用する必要がありました
ステファニー

20

これを処理する1つの方法は、新しいBufferedImageを作成し、そのグラフィックスオブジェクトにスケーリングされた画像を新しいBufferedImageに描画するように指示することです。

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
buffered.getGraphics().drawImage(image, 0, 0 , null);

それはキャストせずにトリックを行う必要があります。


2
作成されたグラフィックインスタンスを
破棄

「作成されたグラフィックインターフェイスを破棄する」方法は?
バッファロー

BufferedImageコンストラクターの型はgetScaledInstanceの型と一致する必要がありますか?
Drazen Bjelovuk 2013

いいえ、TYPEはARGBやRGBAのようなもので、画像データが内部に保存される方法です。アプリケーションにとって最も自然に感じるものを選択してください。BufferedImage。[Autocomplete]と入力するときにオートコンプリートを調べるだけで、すべての選択肢が表示されます
salbeira 2013

3

を取得している場合はsun.awt.image.ToolkitImage、それにImageをキャストしてから、getBufferedImage()を使用してを取得できますBufferedImage

したがって、キャストするコードの最後の行の代わりに、次のようにします。

BufferedImage buffered = ((ToolkitImage) image).getBufferedImage();

7
1)sunパッケージのクラスを使用することは嫌われています。Oracle以外のJDKで使用できるとは限りません。2)メソッドgetBufferedImage()は、バッファリングされた画像がによって内部的に生成された場合にのみ機能しTookitImageます。ほとんどの場合(99%)そうではないため、戻り値はnullです。 ソースリファレンス
kevinarpe 2013

3

Kotlinを使用する場合は、Sri HarshaChilakapatiが提案するのと同じ方法でImageに拡張メソッドを追加できます。

fun Image.toBufferedImage(): BufferedImage {
    if (this is BufferedImage) {
        return this
    }
    val bufferedImage = BufferedImage(this.getWidth(null), this.getHeight(null), BufferedImage.TYPE_INT_ARGB)

    val graphics2D = bufferedImage.createGraphics()
    graphics2D.drawImage(this, 0, 0, null)
    graphics2D.dispose()

    return bufferedImage
}

そして、次のように使用します。

myImage.toBufferedImage()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.