2016-12-07 8 views
0

ウェブブラウザ(Firefox、Chrome、Safari)からの画像をコピー&ペーストしてOSXマシンでの動作を停止しました。 PC。OSX上でイメージをコピー&ペーストすると、Javaでsun.awt.image.MultiResolutionImageが返されるのはなぜですか?

は私が画像/ X-javaの - 画像の風味とデータを期待しているという事実にそれを突き止め、クラス= java.awt.Imageのはいつも私のコードの後半でバッファリングされた画像であることを

BufferedImageである必要がありますので、画像のサイズとデータにアクセスできます。しかし

今の代わりに、それはそれはsun.awt.image.MultiResolutionCachedImageを返し、私はそれが日を実装インタフェースで定義されてgetResolutionVariantsを呼び出す必要がバッファのデータを取得するために、BufferedImageを返します。 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 8

答えて

1

あなたは間違った方向に探しているを使用してJava 9が、イムのJavaパッケージに追加されているようです。誤って想定された特別なケースに別の特別なケースを追加する代わりに、のデータフレーバーとして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'を実装しています。これは、 'image/x-java-image; class = java.awt.Image' mime型を満たす何かの唯一の保証されたプロパティです。アプリケーションがクリップボードに照会するときに別のJavaアプリケーションがカスタム 'Image'実装をクリップボードにプッシュし、' BufferedImage'に変換されない可能性が常にありました。コードはよりシンプルに見えるかもしれませんが、実装の詳細についての前提に基づいています。したがって、実装の詳細が実装の詳細であると非難しています。実装の詳細... – Holger

+0

使いやすい「ImageIO」のような操作は、「BufferedImage」操作としてファイルを使用しないようにJavaを責めることができます。まあ、ここでは汎用の "Image"を "BufferedImage"ソリューションに変換しています。それを考えれば、代わりに 'InputStream'ベースのMIMEタイプを解決し、それを' ImageIO'に渡して 'BufferedImage'を得ることが可能かもしれません。私はそれを試みたことはありません。 – Holger

関連する問題