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.