Unten sind zwei PNG-Bilder:
Optisch sind sie genau identisch - der einzige Unterschied besteht darin, dass einige Pixel einen halbtransparenten Hintergrund haben (Sie können die Bilder herunterladen, um sie zu überprüfen).
Wenn ich diese Bilder jedoch als Bildcursor auf JavaFX-Knoten verwende, erhalte ich das folgende Ergebnis:
Der erste Cursor (ohne teilweise transparente Pixel) ist immer noch scharf, der zweite wird jedoch verzerrt.
Nachdem ich eine Weile mit dem Problem gekämpft hatte, entdeckte ich den Algorithmus, der diesen Unterschied erklärt - den Mischmodus:
Der "erwartete" Weg (den Sie beispielsweise in diesem Browser sehen können) besteht darin, die Summe der Werte pro Kanal zu nehmen, gewichtet mit Alpha-Werten :
(1 - alpha) * background_color + alpha * foreground_color
."JavaFX Cursor" gibt die andere Formel an:
(1 - alpha) * background_color + alpha^2 * foreground_color
(beachten Sie das Quadrat).
Ich habe die Verzerrung entdeckt, kann aber nicht herausfinden, was ich falsch gemacht habe und wie ich dieses Problem beheben kann.
Hier ist der vollständige ausführbare Quellcode für mein Testprogramm:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.ImageCursor;
import javafx.scene.image.Image;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
System.out.println(ImageCursor.getBestSize(32, 32));
primaryStage.setTitle("Hello World!");
StackPane root = new StackPane();
root.setCursor(new ImageCursor(new Image("/test-cursor.png"), 0, 0));
primaryStage.setScene(new Scene(root, 100, 100));
primaryStage.show();
}
}
Wie kann ich solche halbtransparenten Cursor richtig rendern?