It was late...I forgot WritableImage is not a Node.

I wrapped it in an ImageView, added some width/height properties that react on changes in width/height by replacing the WritableImage, and it was almost a drop-in replacement for Canvas for me (the main difference being that you have to re-get the PixelWriter after every size change since its WritableImage is completely replaced each resize).

The resizing when moving the video from monitor to monitor of different sizes worked just as flawless as with Canvas. I did not encounter any memory issues so far (but I only tested for 15 minutes). I'll keep it like this for a while.

--John

Code:

public class ResizableWritableImageView extends ImageView {
  private final DoubleProperty width = new SimpleDoubleProperty();
  public final double getWidth() { return width.get(); }
  public final void setWidth(double width) { this.width.set(width); }
  public final DoubleProperty widthProperty() { return width; }

  private final DoubleProperty height = new SimpleDoubleProperty();
  public final double getHeight() { return height.get(); }
  public final void setHeight(double height) { this.height.set(height); }
  public final DoubleProperty heightProperty() { return height; }

  public ResizableWritableImageView(double w, double h) {
    width.addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        updateImageSize();
      }
    });

    height.addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        updateImageSize();
      }
    });

    width.set(w);
    height.set(h);
  }

  @Override
  public void resize(double w, double h) {
    setWidth(w);
    setHeight(h);
  }

  public PixelWriter getPixelWriter() {
    return ((WritableImage)getImage()).getPixelWriter();
  }

  private void updateImageSize() {
    int w = (int)getWidth();
    int h = (int)getHeight();

    if(w < 1) {
      w = 1;
    }
    if(h < 1) {
      h = 1;
    }

    setImage(new WritableImage(w, h));
  }
}

On 10/08/2013 06:07, Richard Bair wrote:
Scale the imageview?

On Aug 9, 2013, at 8:57 PM, John Hendrikx<hj...@xs4all.nl>  wrote:

On 10/08/2013 05:46, John Hendrikx wrote:
On 9/08/2013 20:15, Richard Bair wrote:
Also the proposed clear() or empty() option only applies to Canvas correct?
i.e. WritableImages don't suffer from these kind of issues and don't require 
such methods?
That is correct (WritableImage we don't provide a 2D API to use to fill the 
buffer, you just bash the pixels yourself however you like, so we don't have to 
buffer anything up).
Hm, I didn't realize WritableImage had the same kind PixelWriter interface.  
For my usecase, where I just render full frames to a PixelWriter so JavaFX can 
display them in some fashion, why should I not use a WriteableImage instead?

Looking at the docs, I see that one limitation is that the WritableImage cannot 
be resized after construction (something that I do use with Canvas), but I 
think I could work around that by just recreating the Image when its size 
changes... I could just wrap a class around it that does this transparently.

Going to take a look if I can rip out the Canvas code and replace it with a 
resizable WritableImage and see what the results are for full screen video 
playback...
Foiled before I even could get started :/

I need the scaleX and scaleY properties of Canvas as well... basically, my 
input video data is always decoded at native size (say 1920x1080) and then 
scaled down or up to fit the screen.  Since I offer a feature that can switch 
to a different attached monitor at any time, even during playback, I cannot 
tell my video source to scale the video for me (it does not offer a way to 
alter this after playback starts).  I haven't given up entirely on 
WritableImage, but this complicates sufficiently that I cannot just create a 
drop-in replacement for Canvas that suits my usecase.

--John



Reply via email to