PNG, JPEG ve GIF dosyalarını yeniden boyutlandırmam gerekiyor. Bunu Java kullanarak nasıl yapabilirim?
PNG, JPEG ve GIF dosyalarını yeniden boyutlandırmam gerekiyor. Bunu Java kullanarak nasıl yapabilirim?
Yanıtlar:
Resmi yükledikten sonra deneyebilirsiniz:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
FWIW Java için imgscalr ( Maven merkezinde mevcuttur) adında basit bir görüntü ölçekleme kitaplığı yayınladım (GitHub'da barındırılan Apache 2 ).
Kütüphane, görüntü ölçeklendirmeye birkaç farklı yaklaşım uygular (Chris Campbell'in birkaç küçük geliştirmeyle artan yaklaşımı dahil) ve isterseniz sizin için en uygun yaklaşımı seçer veya size en hızlı veya en iyi görünümü verir (eğer bunu isteyin).
Kullanım son derece basittir, sadece birkaç statik yöntemdir. En basit kullanım durumu şudur:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
Tüm işlemler görüntünün orijinal oranlarını korur, bu durumda imgscalr'dan görüntünüzü 200 piksel genişliğinde ve 200 piksel uzunluğunda sınırlar içinde yeniden boyutlandırmasını istiyorsunuz ve varsayılan olarak otomatik olarak bunun için en iyi görünen ve en hızlı yaklaşımı seçecektir. belirtilmedi.
Başlangıçta bunun kendi kendini tanıtmaya benzediğini fark ettim (öyle), ancak zaman payımı aynı konuyu araştırmaya harcadım ve farklı sonuçlar / yaklaşımlar / düşünceler / öneriler üretmeye devam ettim ve oturup yazmaya karar verdim. Bir resme sahip olduğunuz ve muhtemelen bunun için bir küçük resim istediğiniz% 80-85'lik kullanım durumlarına hitap edecek basit bir uygulama - ya olabildiğince hızlı ya da olabildiğince güzel (deneyenler için fark edeceksiniz yeterince küçük bir görüntüye BICUBIC enterpolasyonuyla bile Graphics.drawImage yapmak, yine de çöp gibi görünüyor).
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. Ben de senin tarzını beğendim ve daha basit olduğunu düşünüyorum.
Thumbnailator , MIT lisansı altında dağıtılan, akıcı bir arayüze sahip Java için açık kaynaklı bir resim yeniden boyutlandırma kitaplığıdır .
Bu kitaplığı yazdım çünkü Java'da yüksek kaliteli küçük resimler oluşturmak şaşırtıcı derecede zor olabilir ve ortaya çıkan kod oldukça dağınık olabilir. Thumbnailator ile basit ve akıcı bir API kullanarak oldukça karmaşık görevleri ifade etmek mümkündür.
Basit bir örnek
Basit bir örnek olarak, bir görüntünün alınması ve 100 x 100'e yeniden boyutlandırılması (orijinal görüntünün en boy oranının korunarak) ve bir dosyaya kaydedilmesi tek bir ifadede gerçekleştirilebilir:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
Gelişmiş bir örnek
Karmaşık yeniden boyutlandırma görevlerinin gerçekleştirilmesi, Thumbnailator'ın akıcı arayüzü ile basitleştirilmiştir.
Aşağıdakileri yapmak istediğimizi varsayalım:
0.85
,thumbnail.
başa eklenmiş olarak orijinalden alındığı yerThumbnailator'a çevrildiğinde, yukarıdakileri aşağıdakilerle gerçekleştirebileceğiz:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
Görüntü kalitesi ve hız hakkında bir not
Bu kitaplık aynı zamanda, kabul edilebilir çalışma zamanı performansı sağlarken yüksek kaliteli küçük resimler oluşturmak için Chet Haase ve Romain Guy tarafından Filthy Rich Clients'da vurgulanan aşamalı çift doğrusal ölçekleme yöntemini kullanır .
Bunu yapmak için bir kitaplığa ihtiyacınız yok. Bunu Java'nın kendisi ile yapabilirsiniz.
Chris Campbell'ın görüntüleri ölçekleme konusunda mükemmel ve ayrıntılı bir yazısı var - bu makaleye bakın .
Chet Haase ve Romain Guy, Filthy Rich Clients adlı kitaplarında da ayrıntılı ve çok bilgilendirici bir görsel ölçeklendirme yazısına sahipler .
Java Advanced Imaging artık açık kaynak kodludur ve ihtiyacınız olan işlemleri sağlar.
Büyük resimlerle uğraşıyorsanız veya güzel görünen bir sonuç istiyorsanız, bu java'da önemsiz bir görev değildir. Bunu sadece Graphics2D üzerinden bir yeniden ölçeklendirme operasyonu aracılığıyla yapmak, yüksek kaliteli bir küçük resim oluşturmaz. Bunu JAI kullanarak yapabilirsiniz, ancak iyi görünen bir şey elde etmek için tahmin ettiğinizden daha fazla çalışma gerektirir ve JAI'nin JVM'nizi OutOfMemory hatalarıyla patlatmak gibi kötü bir alışkanlığı vardır.
Bundan kurtulabilirseniz, ImageMagick'i harici bir yürütülebilir dosya olarak kullanmanızı öneririm. Kullanımı basit ve işi doğru yapıyor, böylece sizin zorunda kalmazsınız.
Eğer, makinenize imagemagick'in yüklenmesi bir seçenekse , im4java'yı tavsiye ederim . Komut satırı arayüzünde çok ince bir soyutlama katmanıdır, ancak işini çok iyi yapar.
Java API, görüntüler ve görüntü kalitesinin düşürülmesi için standart bir ölçekleme özelliği sağlamaz.
Bundan dolayı JavaCV'den cvResize kullanmaya çalıştım ama sorunlara neden oluyor gibi görünüyor.
Görüntü ölçekleme için iyi bir kitaplık buldum: pom.xml dosyanıza "java-image-scaling" bağımlılığını ekleyin.
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
Maven deposunda bunun için en son sürümü alacaksınız.
Ör. Java programınızda
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
GraphicsMagick Görüntü İşleme Sistemini im4java ile kullanmayı deneyebilirsiniz. Java için bir comand-line arabirimi olarak .
GraphicsMagick'in pek çok avantajı vardır, ancak hepsi için bir tane:
Image Magick'ten bahsedildi. JMagick adında bir JNI ön uç projesi var. Bu özellikle kararlı bir proje değil (ve Image Magick'in kendisinin de çok şey değiştirdiği ve hatta uyumluluğu bozduğu biliniyor). Bununla birlikte, yüksek verimlilikte, düşük gecikme hızında ölçeklendirme gerçekleştirmek için bir üretim ortamında JMagick'i ve Image Magick'in uyumlu bir sürümünü kullanma konusunda iyi bir deneyim yaşadık. Hız, daha önce denediğimiz tüm Java grafik kitaplığından çok daha iyiydi.
Sadece Burkhard'ın cevabını kullanın, ancak grafikleri oluşturduktan sonra bu satırı ekleyin:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Değeri BICUBIC olarak da ayarlayabilirsiniz, bu daha kaliteli bir görüntü üretir ancak daha pahalı bir işlemdir. Ayarlayabileceğiniz başka imge oluşturma ipuçları da var ama enterpolasyonun en dikkate değer etkiyi yarattığını buldum. Çok yakınlaştırmak istiyorsanız, java kodunun büyük olasılıkla çok yavaş olacağını unutmayın. Kaliteden daha yüksek hız için ayarlanan tüm işleme ipuçları ayarlanmış olsa bile, daha büyük görüntülerin% 300 yakınlaştırmada gecikme oluşturmaya başladığını gördüm.
Bu tür işlemler için Marvin'i (saf Java görüntü işleme çerçevesi) kullanabilirsiniz: http://marvinproject.sourceforge.net
Eklentiyi ölçeklendir: http://marvinproject.sourceforge.net/en/plugins/scale.html
Performanslı bir ölçekleyici yazmanın önemsiz olmadığı ortaya çıktı. Açık kaynaklı bir proje için bir kez yaptım: ImageScaler .
Prensipte 'java.awt.Image # getScaledInstance (int, int, int)' da işi yapar, ancak bununla ilgili kötü bir hata var - ayrıntılar için bağlantıma bakın.
GIF Animasyonu için ücretsiz olarak kullanılabilen sınıflarla (AnimatedGifEncoder, GifDecoder ve LWZEncoder) bir çözüm geliştirdim.
Jgifcode kavanozunu indirebilir ve GifImageUtil sınıfını çalıştırabilirsiniz. Bağlantı: http://www.jgifcode.com
aşağıdaki popüler ürünü kullanabilirsiniz: küçük resimleyici
İçe istemiyorsanız imgScalr i test yukarıda @Riyad Kalla cevap gibi çok ince, sen alınan yapabilirsiniz çalışır Peter Walser cevabı başka bir sorun olsa üzerinde @Peter Walser:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}
Aşağıdaki yöntemi deneyin:
ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);