2016-01-08 4 views
2

У меня есть следующий документ SVG:Stop непрозрачности в JavaFX LinearGradient

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<svg id="svg602" 
    xmlns:svg="http://www.w3.org/2000/svg" 
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="324.02335" height="689.724" 
    space="preserve" version="1.0"> 

    <defs id="defs604"> 
    <linearGradient id="linearGradient3034"> 
     <stop id="stop3035" offset="0" 
      style="stop-color:#0000ff;stop-opacity:1" /> 
     <stop id="stop3036" offset="1" 
      style="stop-color:#ffffff;stop-opacity:0;" /> 
    </linearGradient> 
    <linearGradient id="linearGradient3542" 
     xlink:href="#linearGradient3034" 
     x1="10" y1="10" 
     x2="210" y2="210" 
     gradientUnits="userSpaceOnUse" /> 
    </defs> 

    <rect id="r1" x="10" y="10" width="200" height="200" 
     style="fill:url(#linearGradient3542);stroke:none" /> 
</svg> 

Я пытаюсь добиться того же в JavaFX с помощью следующего кода:

import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.CycleMethod; 
import javafx.scene.paint.LinearGradient; 
import javafx.scene.paint.Stop; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class GradientSample extends Application { 
    public static void main(String[] args) { launch(args); } 

    @Override 
    public void start(Stage primaryStage) { 

     Group mainGroup = new Group(); 
     Rectangle r = new Rectangle(10, 10, 200, 200); 

     Stop[] stops = new Stop[] { new Stop(0, new Color(0.0, 0.0, 1.0, 1.0)), 
            new Stop(1, new Color(1.0, 1.0, 1.0, 0.0)) }; 
     LinearGradient lg = new LinearGradient(10, 10, 210, 210, false, CycleMethod.NO_CYCLE, 
               stops); 
     r.setFill(lg); 

     mainGroup.getChildren().add(r); 
     Scene scene = new Scene(mainGroup, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
} 

Однако SVG оказано (в Inkscape), как это:

enter image description here

в то время как Явь AFX сцена визуализируется как это:

enter image description here

Очевидно, что остановка непрозрачности (0,0) второй остановки не рассматривается JavaFX (если я устанавливаю непрозрачность до 1,0 в файле SVG, оно отображается как сцена JavaFX).

Я что-то пропустил или должен считать это ошибкой?

Есть ли другое решение, как достичь непрозрачности Stop, отличного от 1.0 в JavaFX?

ответ

3

Вы нашли ошибку, действительно, но не в непрозрачности!

Сначала я проверил, что непрозрачность работает. Например, вы можете поместить некоторые метки под прямоугольник, и вы увидите это, так что это не проблема.

Итак, я экспортировал изображение как png и отредактировал его. Я обнаружил, что непрозрачность была хорошо интерполирована от 1 до 0, от верхнего левого угла до правого нижнего.

К моему удивлению, красный и зеленый были 0 на каждом пикселе !!

Пытаясь найти сообщение об ошибке, я их не нашел, но у меня появилась идея использовать различные конвейеры рендеринга.

Использование -Dprism.order с параметрами d3d (Windows), es2 (Mac) и sw, все дали тот же неверный результат. Но старый и устаревший j2d отлично работал на Windows!

Чтобы проверить это, я слегка измененный код:

public void start(Stage primaryStage) { 
    Group mainGroup = new Group(); 
    Rectangle r = new Rectangle(0, 0, 200, 200); 

    Stop[] stops = new Stop[] { new Stop(0, new Color(0.0, 0.0, 1.0, 1.0)), 
           new Stop(1, new Color(1.0, 1.0, 1.0, 0.0)) }; 
    LinearGradient lg = new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, stops); 
    r.setFill(lg); 

    mainGroup.getChildren().add(r); 
    Scene scene = new Scene(mainGroup, 200, 200); 
    scene.setFill(Color.TRANSPARENT); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    WritableImage image = scene.snapshot(null); 
    PixelReader pixelReader = image.getPixelReader(); 

    System.out.println("Color: " + pixelReader.getColor((int)image.getWidth()/2, (int)image.getHeight()/2)); 
} 

Бег с регулярными трубопроводами вы увидите этот результат:

Color: 0x0000ff7f 

и только работает с -Dprism.order=j2d вы получите:

Color: 0x7e7eff7f 

Как я уже упоминал ранее, непрозрачность интерполируется, но не цвет RGB: В этом случае кажется, что RGB является одним из первого Stop.

Таким образом, мы можем думать о регрессии в какой-то момент, о котором следует сообщать.

+0

Прохладный, отличный анализ! Будет продолжена в начале следующей недели ... –

+0

https://bugs.openjdk.java.net/browse/JDK-8146778 –

+0

Спасибо, что сообщили об этом –

 Смежные вопросы

  • Нет связанных вопросов^_^