2015-03-04 3 views
1

Мне интересно, есть ли какой-либо путь в GraphicsContext Canvas в JavaFX, чтобы переопределить все пиксели в пути таким образом, чтобы они стали прозрачными снова. Как функция clearRect, но для любого пути.Переопределить путь с прозрачным цветом в javafx Canvas/GraphicsContext

Я посмотрел на различные BlendModes и эффекты, но кажется, что нет никакого способа, чтобы фактически переопределить альфа-значение, которое может быть достигнуто, например,

  • рендеринга прозрачного цвета с оператором Porter/Duff Src
  • рендеринга непрозрачный цвет с globalCompositeOperation назначения отъезда в HTML5

Я был бы очень рад, если бы кто-то знал, как добиться этого без tessellating путь и с помощью нескольких вызовов clearRect. Спасибо.

http://docs.oracle.com/javase/8/javafx/api/javafx/scene/canvas/GraphicsContext.html


Добавление в ответ на первый комментарий: Вместо того, чтобы использовать узел Path Я использую узел Canvas для выполнения рендеринга с использованием GraphicsContext и, таким образом, не представляется возможным модифицировать цвет ранее обработанного пути. Я пытаюсь сделать что-то вроде

Canvas canvas = …; 
final GraphicsContext context = canvas.getGraphicsContext(); 
context.setFill(Color.BLUE); 
context.fillRect(0,0,100,100); 
… 
… 

и позже я хочу, чтобы сбросить пикселы на пути к прозрачному

context.setStroke(Color.TRANSPARENT); 
context.beginPath(); 
context.moveTo(0, 0); 
context.lineTo(10,10); 
… 
context.stroke(); 

Однако, как смешивание применяется это не работает. В других библиотеках воспроизведения можно использовать, например, один из вышеупомянутых способов смешивания/компоновки для достижения этого, но до сих пор я не смог идентифицировать такую ​​функциональность в javafx.

+0

Что вы хотели бы получить, как это выглядит на примере изображения? Либо у вас есть узел Path, либо установите прозрачность, либо нет, и вы перерисовываете путь с цветом фона. – Roland

+0

Я отредактировал этот вопрос с более подробной информацией, чтобы попытаться задать вопросы clearer – illfang

+0

Но что вы ожидаете, когда рисуете на холсте прозрачным цветом? Это не будет иметь никакого эффекта. Просто нарисуйте его цветом фона. Я подозреваю, что вам нужны разные слои. Это не единственный холст. – Roland

ответ

1

Я не нашел механизм для очистки холста в зависимости от пути. Но вот как вы могли бы сделать это вручную:

  • Создайте маску, на которой вы рисуете путь
  • наложения изображений и маска вручную

Пример с синим прямоугольником, который был применен маску с путь:

public class ManualBlendWithMask extends Application { 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) { 

     Group root = new Group(); 

     // create canvas 
     Canvas canvas = new Canvas(200, 200); 
     canvas.setTranslateX(100); 
     canvas.setTranslateY(100); 

     // create canvas with blue rectangle 
     GraphicsContext canvasGC = canvas.getGraphicsContext2D(); 
     canvasGC.setFill(Color.BLUE); 
     canvasGC.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 

     // create mask 
     Canvas mask = new Canvas(canvas.getWidth(), canvas.getHeight()); 
     GraphicsContext maskGC = mask.getGraphicsContext2D(); 
     maskGC.setFill(Color.WHITE); 
     maskGC.fillRect(0, 0, mask.getWidth(), mask.getHeight()); 

     // draw path 
     maskGC.setStroke(Color.BLACK); 
     maskGC.setLineWidth(20); 
     maskGC.beginPath(); 
     maskGC.moveTo(0, 0); 
     maskGC.lineTo(400, 400); 
     maskGC.stroke(); 

     // get image from canvas 
     WritableImage srcImage = new WritableImage((int) canvas.getWidth(), (int) canvas.getHeight()); 
     srcImage = canvas.snapshot(null, srcImage); 

     // get image from mask 
     WritableImage srcMask = new WritableImage((int) mask.getWidth(), (int) mask.getHeight()); 
     srcMask = mask.snapshot(null, srcMask); 

     PixelReader maskReader = srcMask.getPixelReader(); 
     PixelReader imageReader = srcImage.getPixelReader(); 

     int width = (int) srcMask.getWidth(); 
     int height = (int) srcMask.getHeight(); 

     // create dest image 
     WritableImage dest = new WritableImage(width, height); 
     PixelWriter writer = dest.getPixelWriter(); 

     // blend image and mask 
     for (int x = 0; x < width; x++) { 
      for (int y = 0; y < height; y++) { 

       Color maskColor = maskReader.getColor(x, y); 
       Color imageColor = imageReader.getColor(x, y); 

       if (maskColor.equals(Color.WHITE)) { 
        writer.setColor(x, y, imageColor); 
       } 

      } 
     } 

     // clear canvas and fill it with the blended image 
     canvasGC = canvas.getGraphicsContext2D(); 
     canvasGC.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
     canvasGC.drawImage(dest, 0, 0); 

     // draw background with gradient 
     Rectangle rect = new Rectangle(400, 400); 
     rect.setFill(new LinearGradient(0, 0, 1, 1, true, CycleMethod.REFLECT, new Stop(0, Color.RED), new Stop(1, Color.YELLOW))); 

     // show nodes 
     root.getChildren().addAll(rect, canvas); 

     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 

    } 

} 

Конечно, было бы лучше, если бы кто-нибудь мог придумать пример использования BlendModes. enter image description here

+0

Благодарим вас за подробный ответ. Поскольку ваш ответ показал другой подход к решению проблемы, я согласен с вашим ответом, поскольку, как кажется, никто не знает способа реализовать это с помощью BlendModes или подобных методов, которые, несомненно, потребуют меньше ресурсов. Спасибо. – illfang

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