2016-12-07 8 views
0

Копирование и вставка изображений из веб-браузера (Firefox, Chrome и Safari) перестала работать на моей машине OSX, это нормально ПК.Почему копирование и вставка изображений на OSX теперь возвращает sun.awt.image.MultiResolutionImage в Java 8

Я отслеживал его до того, что я ожидал данные со вкусом изображения/х-ява-изображения, класс = java.awt.Image всегда быть буферное изображение позже в моем коде

Мне нужно, чтобы это было BufferedImage, поэтому я могу найти размер изображения и получить доступ к данным.

Однако теперь вместо него возвращает BufferedImage он возвращает sun.awt.image.MultiResolutionCachedImage и получить буферизованные данные мне нужно позвонить getResolutionVariants, который определен только в интерфейсе он реализует солнца. awt.image.MultiResolutionImage

Итак, теперь мой код должен ссылаться непосредственно на классы солнца, неужели это неправильно?

Image  image  = null; 
    ImageCell imageCell = null; 
    try 
    { 
     image = (Image) trans.getTransferData(FileDropTarget.imageFlavor); 
    } 
    catch(Exception e) 
    { 
     MainWindow.logger.log(Level.WARNING,"Unable to extract image from drop data:"+e.getMessage(),e); 
    } 


    if(image!=null && image instanceof sun.awt.image.MultiResolutionImage) 
    { 
     for(Image i:mri.getResolutionVariants()) 
     { 
      if(i instanceof BufferedImage) 
      { 
       ImageData imageData = new ImageData((BufferedImage) i, "downloaded:" + new Random().nextInt()); 
       imageCell = new ImageCell(imageData); 
       return imageCell; 
      } 
     } 
    } 

Другая вещь, которую я заметил, если я ставлю некоторые отладки он всегда использует MultiResolutionCachedImage даже если есть на самом деле только одно изображение!

Это действительно кажется, эти классы были добавлены в пакет Java в Java 9, но Im использованием Java 8.

ответ

1

Вы смотрите в неправильном направлении. Вместо того, чтобы добавить другой специальный случай к вашему ошибочно принятому специальному случаю, вы должны искать решение, которое работает для любого Image, поскольку атрибут данных image/x-java-image;class=java.awt.Image никогда не гарантировал доставку определенного типа изображения, следовательно, ссылка на интерфейс java.awt.Image ...

общее решение, основанное на том, как предполагается, будет обрабатываться так 1.1, но улучшены с использованием новых возможностей Java, является

public static BufferedImage getImage(Image image) { 
    if(image instanceof BufferedImage) return (BufferedImage)image; 
    Lock lock = new ReentrantLock(); 
    Condition size = lock.newCondition(), data = lock.newCondition(); 
    ImageObserver o = (img, infoflags, x, y, width, height) -> { 
     lock.lock(); 
     try { 
      if((infoflags&ImageObserver.ALLBITS)!=0) { 
       size.signal(); 
       data.signal(); 
       return false; 
      } 
      if((infoflags&(ImageObserver.WIDTH|ImageObserver.HEIGHT))!=0) 
       size.signal(); 
      return true; 
     } 
     finally { lock.unlock(); } 
    }; 
    BufferedImage bi; 
    lock.lock(); 
    try { 
     int width, height=0; 
     while((width=image.getWidth(o))<0 || (height=image.getHeight(o))<0) 
      size.awaitUninterruptibly(); 
     bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g = bi.createGraphics(); 
     try { 
      g.setBackground(new Color(0, true)); 
      g.clearRect(0, 0, width, height); 
      while(!g.drawImage(image, 0, 0, o)) data.awaitUninterruptibly(); 
     } finally { g.dispose(); } 
    } finally { lock.unlock(); } 
    return bi; 
} 

вы можете добавить другие особые случаи, но вы всегда должны иметь обработку произвольный запасной вариант Image реализации.

+0

Спасибо. У меня есть несколько моментов в этом вопросе, во-первых, на самом деле это с изображениями MultiResolution, во-вторых, вы используете код с низким уровнем (для java) здесь - я бы сказал, что мой код бесконечно читаем, в-третьих, моя основная мысль заключалась в том, что было неправильно для jre использовать открытый класс и интерфейс Java, но вы не думаете, что это неправильно. –

+0

Java возвращает то, что реализует 'public' интерфейс' java.awt.Image', как это всегда было. Это единственное гарантированное свойство чего-то, выполняющего тип mime-образа image/x-java-image; class = java.awt.Image. Всегда возможно, что другое приложение Java подталкивает пользовательскую реализацию «Image» в буфер обмена, который не конвертируется в «BufferedImage», когда ваше приложение запрашивает буфер обмена. Ваш код может выглядеть проще, но он основан на предположениях о деталях реализации. Таким образом, вы обвиняете Java в деталях реализации, являющихся ... конкретными деталями реализации ... – Holger

+0

Вы * можете * обвинять Java в том, что вы не предоставляете простой в использовании «gimme the clipboard как« BufferedImage », как' ImageIO' для файлов, но ну, здесь у вас есть общий «конвертировать любое« изображение »в« BufferedImage ». Подумав об этом, можно было бы установить вместо mime-типа 'InputStream' и передать его в' ImageIO', чтобы получить «BufferedImage». Я никогда не пробовал этого. – Holger