Below are two PNG images:
Visually they are exactly identical - the only difference is that one has semi-transparent background in some of the pixels (you can download the images to check it).
But when I use those images as an ImageCursor on JavaFX nodes, I get the following result:
First cursor (without partially transparent pixels) is still crisp, but the second gets distorted.
After fighting with the problem for a while, I discovered the algorithm that accounts for this difference - blending mode:
"Expected" way (that you can see in this browser, for example) is to take sum of values per channel, weighted by alpha values:
(1 - alpha) * background_color + alpha * foreground_color
."JavaFX Cursor" gives the different formula:
(1 - alpha) * background_color + alpha^2 * foreground_color
(note the square).
I discovered the distortion, but I can't figure out what I did wrong and how I can correct this problem.
Here's the complete runnable source code for my testing program:
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(); } }
How can I achieve proper rendering of such semi-transparent cursors?
0 comments:
Post a Comment