2013-04-18 12 views
10

Ist es möglich, ein skaliertes Bild in einem ImageView in JavaFX 2.2 zu rendern, ohne dass eine Glättung vorgenommen wurde? Ich rende ein 50x50-Bild mit setSmooth (false) in ein 200x200 ImageView, sodass jedes Pixel im Quellbild einem 4x4-Quadrat auf dem Bildschirm zugeordnet werden sollte.JavaFX ImageView ohne Glättung

Allerdings glättet der resultierende Render noch das Quellpixel über alle 16 Zielpixel. Kennt jemand eine Möglichkeit, dies zu tun, ohne jedes Pixel manuell in ein neues Bild zu kopieren?

+0

Sie könnten Canvas versuchen, um maximale Kontrolle zu bekommen. –

+0

Leider glaube ich nicht, dass es eine Möglichkeit, es in einer Leinwand zu tun, auch nicht. Was sie wirklich tun müssen, ist, dass wir unsere eigenen 2D-Filter erstellen können (ich nehme an, dass sie in JavaFX "Effekte" genannt werden). – ajselvig

+0

Meine Antwort wurde mit Ideen zur Implementierung eines eigenen Bildfilters aktualisiert. – jewelsea

Antwort

15

In JavaFX 2.2 ImageView wird immer einige Glättung unabhängig von der smooth Hinweis, den Sie an die ImageView liefern.

(Basierend auf Tests mit Java 7u15 und Windows 7 mit einer ATI HD4600 Grafikkarte).

Vielleicht ist es ein Fehler, ImageView wird immer glatt die Image, aber die Dokumentation nicht wirklich genau angeben, was Glättung tut oder nicht, so ist es schwer zu sagen, was seine wahre Absicht ist. Sie können einen Verweis auf diese Frage an die openjfx-dev mailing list senden oder ein Problem in der JavaFX issue tracker protokollieren, um eine bessere Meinung von einem Entwickler zu erhalten.


versuchte ich ein paar verschiedene Methoden für die Bildskalierung:

  1. Maßstab im Image constructor.
  2. Maßstab in ImageView mit fitWidth/fitHeight.
  3. Skala unter Verwendung der scaleX/scaleY Eigenschaften auf einem ImageView.
  4. Skalieren Sie durch Abtasten der Image mit einer PixelReader und Erstellen eines neuen Bildes mit einer PixelWriter.

fand ich, dass Methoden 1 & 4 in einem scharfen verpixelten Bild geführt, wie Sie wünschen und 2 & 3 in einem unscharfen Bild aliased geführt.

robot-sampling

Sample code die obige Ausgabe zu erzeugen.


Aktualisierung mit Ideen auf Ihrem eigenen Bild Filter

Umsetzung

A JavaFX Wirkung nicht die gleiche wie die Filter für die Bildladeroutinen verwendet, obwohl ein Effekt ein Bild filtern erstellt werden konnte. In der öffentlich dokumentierten JavaFX 2.2-API zur Unterstützung der Erstellung von benutzerdefinierten Effekten kann sich die Erstellung eines benutzerdefinierten Effekts als schwierig erweisen.

Die native code for image support wurde vor kurzem Open Source als Teil der openjfx project, so dass Sie sehen können, um zu sehen, wie die Filterung derzeit implementiert ist.

Sie können auch eine feature request against the JavaFX runtime project ablegen, um "uns die Möglichkeit zu geben, eigene 2D-Filter zu erstellen".

+1

Sie immer so beeindruckende Antworten jewelsea geben: D –

+1

Ja, vielen Dank für die ausführliche Antwort. Ich bin zu demselben Schluss gekommen und habe # 4 umgesetzt. Die Umsetzung selbst ist trivial, aber ich fürchte, dass es viel langsamer als # 2 oder # 3 (obwohl ich dies noch nicht überprüft haben). – ajselvig

+2

Es ist zwei Jahre her seit dieser Antwort. Weiß jemand, ob dies in JavaFX behoben wurde? –

1

Ich weiß, das ist etwas älter, aber ich hatte vor kurzem ein Bedarf für eine solche Image und die folgende kleine Hack tut genau das, was ich auf meinem (Windows) bearbeiten möchten. Keine Garantie, dass es überall funktioniert.

Der Trick hier ist, dass die Textur wieder verwendet wird, so bleibt die lineare Filtereinstellung "klebrig". Warum NGImageView konnte einfach nicht die „glatte“ Flag, um die Einstellung lineare Filterung der Textur passieren ist jedoch über mich.

+0

Sieht so aus, als wollten sie das nicht tun. – Nolan

+0

Dies funktionierte für Java 8, aber es sieht so aus, als ob die hier genannten Funktionen in Java 9 umbenannt und auf private Funktionen gesetzt wurden. Es sieht nicht so aus, als könne es ohne wesentliche Änderungen an 'ImageView' und' ImageViewHelper' überschrieben werden . Wer hat herausgefunden, wie man die neuen Einschränkungen in Java 9 umgehen kann? – ddukki

0

Wenn Sie den folgenden Konstruktor Martin Sojka Antwort hinzufügen können Sie einfach die javafx Bild an den Konstruktor übergeben. Trotz der Warnungen über veraltete Funktionen funktioniert seine Antwort immer noch gut (auf JDK 1.8_121).

public PixelatedImageView (javafx.scene.image.Image image) { 
    super(image); 
}