7

I have created an image on a Canvas which is scaled down for display using a transformation. It is also in a ScrollPane which means only a part of the image is visible.

I need to take a snapshot of the entire canvas and save this as a high-resolution image. When I use Canvas.snapshot I get a Writable image of the visible part of the image after scaling down. This results in a low-res partial image being saved.

So how do I go about creating a snapshot which includes the entire canvas (not only the viewport of the scrollpane) and with the resolution before the transformation downwards?

I am not doing anything fancy currently, just this:

public WritableImage getPackageCanvasSnapshot()
{
    SnapshotParameters param = new SnapshotParameters();
    param.setDepthBuffer(true);
    return packageCanvas.snapshot(param, null);
}
Cobusve
  • 1,572
  • 10
  • 23

2 Answers2

14

I did the following to get a canvas snapshot on a Retina display with a pixelScaleFactor of 2.0. It worked for me.

public static WritableImage pixelScaleAwareCanvasSnapshot(Canvas canvas, double pixelScale) {
    WritableImage writableImage = new WritableImage((int)Math.rint(pixelScale*canvas.getWidth()), (int)Math.rint(pixelScale*canvas.getHeight()));
    SnapshotParameters spa = new SnapshotParameters();
    spa.setTransform(Transform.scale(pixelScale, pixelScale));
    return canvas.snapshot(spa, writableImage);     
}
mipa
  • 10,369
  • 2
  • 16
  • 35
  • I will try it out. Did this give you the full canvas or the current viewport? – Cobusve Sep 02 '15 at 00:36
  • 2
    Awesome, that was perfect, so the trick is to supply an image which is the size of the canvas, if you ask it to create it then it only creates the size of the viewport,, and by scaling it up into your destination you can get exactly what I asked for. It all makes sense now. Perfect ! – Cobusve Sep 02 '15 at 00:51
  • `double pixelScale` how can we retrieve this param to make method more universal? – deviant Nov 06 '17 at 16:22
0

All you need to do is to set the scale in param.

For example, to generate snapshot of width 1600 pixel while keeping aspect ratio do this:

public WritableImage getPackageCanvasSnapshot()
{
    SnapshotParameters params = new SnapshotParameters();
    double s = 1600.0 / packageCanvas.getBoundsInLocal().getWidth();
    params.setTransform(new Scale(s, s));
    return packageCanvas.snapshot(params, null);
}
Saeid Nourian
  • 1,606
  • 15
  • 32