为什么在 OSX 上复制和粘贴图像现在 return sun.awt.image.MultiResolutionImage 在 Java 8
Why does copy and paste of images on OSX now return sun.awt.image.MultiResolutionImage in Java 8
从 Web 浏览器(Firefox、Chrome 和 Safari)复制和粘贴图像在我的 OSX 机器上停止工作,在 PC 上没问题。
我追踪到这样一个事实,即我希望具有 image/x-java-image;class=java.awt.Image 风格的数据始终是稍后在我的代码中缓冲图像
我需要它是一个 BufferedImage 这样我就可以找到图像的大小并访问数据。
但是现在它不再返回 BufferedImage,而是 returns sun.awt.image.MultiResolutionCachedImage,要获取缓冲数据,我需要调用 getResolutionVariants 仅在其实现的接口中定义 sun.awt.image.MultiResolutionImage
所以现在我的代码必须直接引用 sun classes,这肯定是错误的吧?
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,即使实际上只有一个图像!
这些 class 似乎确实已添加到 Java 9 中的 java 包中,但我使用的是 Java 8.
你看错方向了。您应该寻找适用于任何 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
实现。
从 Web 浏览器(Firefox、Chrome 和 Safari)复制和粘贴图像在我的 OSX 机器上停止工作,在 PC 上没问题。
我追踪到这样一个事实,即我希望具有 image/x-java-image;class=java.awt.Image 风格的数据始终是稍后在我的代码中缓冲图像
我需要它是一个 BufferedImage 这样我就可以找到图像的大小并访问数据。
但是现在它不再返回 BufferedImage,而是 returns sun.awt.image.MultiResolutionCachedImage,要获取缓冲数据,我需要调用 getResolutionVariants 仅在其实现的接口中定义 sun.awt.image.MultiResolutionImage
所以现在我的代码必须直接引用 sun classes,这肯定是错误的吧?
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,即使实际上只有一个图像!
这些 class 似乎确实已添加到 Java 9 中的 java 包中,但我使用的是 Java 8.
你看错方向了。您应该寻找适用于任何 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
实现。