2013-04-18 10 views
10

スムージングを適用せずにJavaFX 2.2のImageViewでスケーリングしたイメージをレンダリングすることはできますか? setSmooth(false)を使って50x50イメージを200x200 ImageViewにレンダリングするので、ソースイメージの各ピクセルは画面上の4x4四角にマップされます。スムージングなしのJavaFX ImageView

しかし、結果として得られるレンダリングは、16個のすべての宛先ピクセルにわたってソースピクセルをスムーズにします。誰もが、手動で各ピクセルを新しいイメージにコピーすることなくこれを行う方法を知っていますか?

+0

最大限の制御を得るためにCanvasを試すことができます。 –

+0

残念ながら私はキャンバスでもそれを行う方法はないと思います。彼らが本当に必要とするのは、私たち自身の2Dフィルタを作ることです(JavaFXでは "Effects"と呼ばれていると思います)。 – ajselvig

+0

自分のイメージフィルタを実装するアイデアを私の答えに更新しました。 – jewelsea

答えて

15

JavaFX 2.2のImageViewは、ImageViewに提供するヒントのうち、smoothのヒントに関係なく、常にスムージングを実行します。

(ATI HD4600グラフィックカードを搭載したJava 7u15およびWindows 7を使用したテストに基づく)

おそらくImageViewImageを滑らかにするバグですが、ドキュメントでは実際にスムージングが実行する処理と実行しない処理が正確に指定されていないため、実際の目的が何であるかは分かりません。この質問への参照をopenjfx-dev mailing listに投稿するか、JavaFX issue trackerに問題を記録して、開発者からより専門的な意見を得ることができます。 Image constructor

  1. スケール:

    は私が画像をスケーリングするための、いくつかの異なる方法を試してみました。
  2. スケールはImageViewfitWidth/fitHeightである。
  3. scaleX/scaleYのプロパティをImageViewで使用してスケールします。
  4. ImagePixelReaderでサンプリングし、PixelWriterで新しい画像を作成してスケールします。

私はあなたが望むような方法1 & 4は、シャープなピクセル化画像をもたらし、2 & 3がぼやけエイリアス画像が生じたことがわかりました。

robot-sampling

Sample code上記出力を生成します。


画像をフィルタリングするためのエフェクトを作成することができてもJavaFXの効果は、画像の読み込みルーチンに用いられるフィルタと同じではありません

独自の画像フィルタを実装上のアイデアを更新します。 JavaFX 2.2では、カスタムエフェクトの作成をサポートするために公開されているAPIが公開されているため、カスタムエフェクトの作成が難しい場合があります。

最近、は、openjfx projectの一部としてソースを公開しています。そのため、フィルタリングが現在どのように実装されているかを見ることができます。

feature request against the JavaFX runtime projectを「私たち自身の2Dフィルタを作成できるようにする」こともできます。

+1

あなたはいつもそのような印象的な答えを与えますjewelsea:D –

+1

はい、詳細な答えをいただきありがとうございます。私は同じ結論に達して、#4の実装を終了しました。実装そのものは簡単ですが、#2や#3よりはるかに遅いのではないかと心配しています(これはまだ検証していませんが)。 – ajselvig

+2

この回答から2年経ちました。これがJavaFXで修正されているかどうかは誰にも分かりますか? –

1

これはもう少し古いですが、私は最近、このようなImageViewの必要性があり、以下の小さなハックが私の(Windows)マシンでしたいことを正確に行います。どこでも動作する保証はありません。

import com.sun.javafx.sg.prism.NGImageView; 
import com.sun.javafx.sg.prism.NGNode; 
import com.sun.prism.Graphics; 
import com.sun.prism.Texture; 
import com.sun.prism.impl.BaseResourceFactory; 

import com.sun.prism.Image; 
import javafx.scene.image.ImageView; 

@SuppressWarnings("restriction") 
public class PixelatedImageView extends ImageView { 
    @Override protected NGNode impl_createPeer() { 
     return new NGImageView() { 
      private Image image; 

      @Override public void setImage(Object img) { 
       super.setImage(img); 
       image = (Image) img; 
      } 

      @Override protected void renderContent(Graphics g) { 
       BaseResourceFactory factory = (BaseResourceFactory) g.getResourceFactory(); 
       Texture tex = factory.getCachedTexture(image, Texture.WrapMode.CLAMP_TO_EDGE); 
       tex.setLinearFiltering(false); 
       tex.unlock(); 
       super.renderContent(g); 
      } 
     }; 
    } 
} 

トリックは、テクスチャが再利用されるため、線形フィルタリングの設定が「スティッキー」のままです。なぜなら、NGImageViewは、テクスチャの線形フィルタリング設定に「スムーズ」フラグを単に渡すことができなかったからです。

+0

彼らはあなたがこれをしたくないように見えます。 – Nolan

+0

これはJava 8でも機能しましたが、ここで述べた関数の名前が変更され、Java 9ではprivate関数に設定されているようです。ImageViewとImageViewHelperに大きな変更を加えることなく同じ方法で上書きできるようには見えません。 。 誰もがJava 9の新しい制限を回避する方法を考え出しましたか? – ddukki

0

Martin Sojkaの答えに次のコンストラクタを追加すると、単にjavafxイメージをコンストラクタに渡すことができます。また、deprecated関数に関する警告にもかかわらず、彼の答えはまだうまくいきます(JDK 1.8_121)。

public PixelatedImageView (javafx.scene.image.Image image) { 
    super(image); 
} 
関連する問題