Ниже приведены два изображения PNG:
Визуально они абсолютно идентичны - единственное отличие состоит в том, что в некоторых пикселях имеется полупрозрачный фон (вы можете скачать изображения, чтобы проверить это).
Но когда я использую эти изображения в качестве курсора изображения на узлах JavaFX, я получаю следующий результат:
Первый курсор (без частично прозрачных пикселей) по-прежнему четкий, но второй искажается.
Поработав с проблемой некоторое время, я обнаружил алгоритм, который учитывает эту разницу - режим смешивания:
"Ожидаемый" способ (который вы можете увидеть в этом браузере, например) - это взять сумму значений на канал, взвешенную по альфа-значениям:
(1 - alpha) * background_color + alpha * foreground_color
."Курсор JavaFX" дает другую формулу:
(1 - alpha) * background_color + alpha^2 * foreground_color
(обратите внимание на квадрат).
Я обнаружил искажение, но я не могу понять, что я сделал неправильно, и как я могу исправить эту проблему.
Вот полный исполняемый исходный код моей программы тестирования:
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();
}
}
Как мне добиться правильного рендеринга таких полупрозрачных курсоров?