Görüntüyü BufferedImage'a dönüştüren Java


83

StackOverflow'da bu bağlantı gibi bir soru zaten var ve kabul edilen cevap "çevrim" dir:

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

Programımda deniyorum:

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;

Ne yazık ki çalışma zamanı hatası alıyorum:

sun.awt.image.ToolkitImage java.awt.image.BufferedImage'a dönüştürülemez

Açıkçası döküm işe yaramıyor.
Soru: Görüntüyü BufferedImage'a dönüştürmenin doğru yolu nedir (veya var mı)?


arabelleğe alınmış görüntüyü ölçeklemek istiyorsanız, bunu deneyin [ stackoverflow.com/questions/4216123/… [1]: stackoverflow.com/questions/4216123/…
user902383

7
Kayıt için, bunu söyleyen derleyici DEĞİLDİR. Aslında bir çalışma zamanı hatası görüyorsunuz ... bir derleme hatası değil.
Stephen C

1
Haklısın. Bunu işaret ettiğiniz için teşekkürler. Soruyu buna göre düzenleyeceğim.
Arek Wilk

@ user902383 Soruma doğrudan cevap vermeseler bile - bunlar da harika çözümler.
Arek Wilk

Small Thing to OP: Yöntem , imzasıyla ImageIO.read(File)a döndürür BufferedImage. ( Referans ) Önce bir Imagedeğişkene atama, sonra yazı tipine dönüştürme yapmaya gerek yoktur BufferedImage. Bu, kodunuzu okuyan insanların kafasını karıştırabilir.
kevinarpe

Yanıtlar:


124

Bir itibaren Java Oyun Motoru :

/**
 * 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 uygulamalarının ortalama bellek tüketimine bakılırsa, diğer geliştiriciler kesinlikle bellek konusunda biraz endişelenmiyorlar.
Tomáš Zato - Monica'yı eski durumuna getir

1
@ TomášZato C ++ dünyasından görünüyorsunuz, görüntü verilerinin piksellerinin belleğini yeniden kullanmayı düşünüyorsunuz. Önceki yorumumdan kastım, bu durumda hafıza konusunda endişelenmenize gerek yok, çünkü GC bunu Java'da halledecek.
Sri Harsha Chilakapati

2
@SriHarshaChilakapati Yani çöp toplayıcılar herhangi bir kaynak tüketmiyor mu? GC sizi yalnızca hafızayı çevreleyen koddan kurtarır . Bir donanım sınırını ortadan kaldırmaz.
Andrew Sannier

5
Bu takdirde çalışmaz Image, çünkü henüz yüklü değil getWidth(null)veya getHeight(null)dönecektir -1durumda
kararır

1
BufferedImage.TYPE_INT_RGBKüçük resmimin renklerini doğru almak için ARGB yerine kullanmak zorunda kaldım
Stephanie

20

Bunu halletmenin bir yolu, yeni bir BufferedImage oluşturmak ve grafik nesnesine ölçeklenmiş görüntünüzü yeni BufferedImage'a çizmesini söylemektir:

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);

Bu hile yapmadan yapmalı.


2
Oluşturulan grafik örneklerini
atmayı

"Oluşturulan grafik arayüzleri nasıl atılır"?
Buffalo

BufferedImage yapıcısındaki tür, getScaledInstance içindeki türle eşleşmeli mi?
Drazen Bjelovuk

Hayır, TÜR, ARGB veya RGBA gibi, görüntü verilerinin dahili olarak depolanma şeklidir - uygulamanız için en doğal olanı seçin; BufferedImage yazarken Otomatik Tamamlamanıza bakın. Tüm seçenekleri görmek için [Otomatik Tamamlama]
salbeira

3

Eğer bir geri alıyorsanızsun.awt.image.ToolkitImage , Görüntüyü buna çevirebilir ve sonra getBufferedImage () kullanarak BufferedImage.

Dolayısıyla, yayınladığınız son kod satırınız yerine şunları yaparsınız:

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

7
1) sunPaket içindeki sınıfları kullanmak hoş karşılanmaz . Oracle olmayan JDK'larda kullanılabilir olmaları garanti edilmez. 2) Yöntem getBufferedImage()yalnızca arabelleğe alınan görüntü dahili olarak tarafından oluşturulmuşsa çalışır TookitImage. Çoğu zaman (% 99) öyle değildir, dolayısıyla dönüş değeri öyledir null. Kaynak Referansı
kevinarpe

3

Kotlin kullanıyorsanız, Sri Harsha Chilakapati'nin önerdiği şekilde Görüntüye bir genişletme yöntemi ekleyebilirsiniz.

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
}

Ve bunu şu şekilde kullanın:

myImage.toBufferedImage()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.