为什么在OSX上复制和粘贴图像现在返回Java 8中的sun.awt.image.MultiResolutionImage

时间:2016-12-07 11:12:20

标签: java java-8 awt bufferedimage

从我的OSX计算机上复制并粘贴来自网络浏览器(Firefox,Chrome和Safari)的图像,在PC上就可以了。

我追踪到这样一个事实:我希望数据具有 image / x-java-image; class = java.awt.Image 的味道,以便在我的代码中稍后成为缓冲图像

我需要它是 BufferedImage 所以我可以找到图像的大小并访问数据。

然而现在它不是返回一个BufferedImage而是返回 sun.awt.image.MultiResolutionCachedImage ,并且要获取我需要调用的 getResolutionVariants 的缓冲数据在它实现的接口中定义 sun.awt.image.MultiResolutionImage

所以现在我的代码必须直接引用sun类,这肯定是错的?

   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 9中的java包中,但我使用的是Java 8。

1 个答案:

答案 0 :(得分:2)

你正在寻找错误的方向。您应该寻找适用于任何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实现。