2010-06-08 25 views
20

Web sitemizde yüklenen fotoğrafları yeniden boyutlandırmak için Java2D kullanıyoruz, ancak biz sorunu (görünüşte eskisinin, bkz .: http://forums.sun.com/thread.jspa?threadID=5425569) girmek - Birkaç belirli JPEG yükseltmek bir CMMException biz ImageIO.read() onların ikili verileri içeren bir InputStream çalıştıklarında : JPEG dosyalarını okumak için ImageIO'ya% 100 Java alternatif var mı?

java.awt.color.CMMException: Invalid image format 
at sun.awt.color.CMM.checkStatus(CMM.java:131) 
at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89) 
at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516) 
at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114) 
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method) 
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082) 
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897) 
at javax.imageio.ImageIO.read(ImageIO.java:1422) 
at javax.imageio.ImageIO.read(ImageIO.java:1326) 
    ... 

Biz belirli fotoğraf makinelerinde çekilen fotoğraflara indirdim (bizim ImageIO.read() çağrı, servlet kodu ve şekildedir yığın izleme, kalanını snipped), ve bunu tetikleyiciler bir fotoğraf seçilmiş Bu hata: http://img214.imageshack.us/img214/5121/estacaosp.jpg. Bunun sadece Sun'ın JVM'sinde (Linux ve Mac'de, sadece 1.6.0_20'de test edildi) fark edildiğini fark ettik - OpenJDK'li bir test makinesi, muhtemelen JPEG okuyucunun farklı bir uygulamasından dolayı aynı fotoğrafları bir aksama olmadan okur.

Ne yazık ki, biz JVM'leri üretimde değiştiremiyoruz veya ImageMagick (http://www.imagemagick.org/) gibi yerel bağımlı çözümler kullanamıyoruz.

Bunu göz önünde bulundurarak, sorum şu: Bağlı olan gibi fotoğrafları işleyebilen ImageIOs JPEG okuyucu için bir değişiklik var mı? Değilse, kullanabileceğimiz başka bir% 100 saf Java fotoğraf yeniden boyutlandırma çözümü var mı?

Teşekkür ederiz!

+0

Bu arada, ImageIO'nun CMYK görüntülerini işleme koymadığının farkındayım (http://stackoverflow.com/questions/2408613/problem-reading-jpeg-image-using-imageio-readfile-file adresinde olduğu gibi).Ama örnek bir RGB (Mac Önizleme söz konusu olduğunda, birisi bunu onaylayabilirse memnun olur) – chesterbr

+0

Oracle/Sun bug veritabanında bir hata açtım: http://bugs.sun.com/bugdatabase /view_bug.do?bug_id=7064516 Hala ilgilenmeye devam ediyorsanız bunun için oy verin! –

cevap

11

biri muhtemelen yararlı kütüphane için elinden Java Advanced Imaging Library (JAI)

biraz daha karmaşık ImageIO kullanmaktan daha ama hızlı test Sadece değiştiklerini ran olabilir Bu kütüphaneyi kullanarak hep açık ve ekran bağlandığınız sorunlu görüntü dosyası.

public static void main(String[] args) { 
     RenderedImage image = JAI.create("fileload", "estacaosp.jpg"); 

     float scale=(float) 0.5; 

     ParameterBlock pb = new ParameterBlock(); 
     pb.addSource(image); 

     pb.add(scale); 
     pb.add(scale); 
     pb.add(1.0F); 
     pb.add(1.0F); 

     pb.add(new InterpolationNearest());// ;InterpolationBilinear()); 
     image = JAI.create("scale", pb); 

     // Create an instance of DisplayJAI. 
     DisplayJAI srcdj = new DisplayJAI(image); 

     JScrollPane srcScrollPaneImage = new JScrollPane(srcdj); 

// Use a label to display the image 
     JFrame frame = new JFrame(); 

     frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

Bu kodu çalıştırdıktan sonra görüntü düzgün görünüyor. Bu size yardımcı oluyor umut

String filename2 = new String ("tofile.jpg"); 
    String format = new String ("JPEG"); 
    RenderedOp op = JAI.create ("filestore", image, filename2, format); 

: Daha sonra

Ve dosyayı kaydetmek istiyorsanız nihayet sadece çağırabilirsiniz ParamaterBlock

kullanılarak% 50 boyutlandırılır. İyi şanslar.

+0

Kesinlikle öyle! "Başsız" bir kurulumda ne kadar iyi çalışacağını kontrol etmeliyim, ama bunun işe yarayabileceğine inanıyorum. Teşekkür ederim! – chesterbr

+1

Sadece bilmeniz için, geliştiricilerimiz bu çözümü uyguladı ve bir cazibe gibi çalıştı. Tekrar teşekkür ederim! – chesterbr

+1

ölü bağlantı, lütfen http://www.oracle.com/technetwork/java/current-142188.html veya şimdi ne varsa güncelleyin. – user1133275

7

Aynı sorunla karşılaştım. JAI'yi modası geçmiş gibi kullanmakta isteksizdim ama en kısa çözüm gibi görünüyor.

public static BufferedImage read(InputStream is) throws IOException { 
    try { 
     // We try it with ImageIO 
     return ImageIO.read(ImageIO.createImageInputStream(is)); 
    } catch (CMMException ex) { 
     // If we failed... 
     // We reset the inputStream (start from the beginning) 
     is.reset(); 
     // And use JAI 
     return JAI.create("stream", SeekableStream.wrapInputStream(is, true)).getAsBufferedImage(); 
    } 
} 
8

Eski yazı ama ileride yararlanmak üzere:

Bu kod güneşin ImageIO (hızlı) veya JAI kullanarak bu sorun ortaya bazı durumlarda, içinde kullanarak bir BufferedImage bir InputStream dönüştürür

Bu sorudan ve buradaki bağlantılardan ilham alarak, ImageIO için JPEG görüntülerini bu tür "kötü" ICC renk profilleriyle destekleyen bir JPEGImageReader eklentisi yazdım ("sorun", ICC profilindeki oluşturma amacı Java ile uyumlu değil. ColorConvertOp). Sade bir Java ve JAI gerektirmez.

Kaynak kodu ve bağlantılı ikili yapılar GitHub'daki TwelveMonkeys project'dan ücretsiz olarak edinilebilir.

İlgili konular