Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative(s) of converting Canvas to WritableImage

I'm developing an application which needs a lot of comparing image data in JavaFX. For that comparing, I need to to get rgb data of pixels in the images. Let's say that the picture I need to compare is Picture1 and Picture2. Picture1 is an input picture selected by the user. Picture2 is a drawing that I make programmatically.

AFAIK, the only way to get rgb data per pixel in JavaFX is with PixelReader of Image. It's fine for the Picture1 since it's an input. But I need to do a drawing on Picture2 and Picture2 is a Canvas (I draw polygons on Picture2 and because drawing pixel by pixel with PixelWriter is a bit complicated IMO) and doesn't have a PixelReader or something with similar functionality. So my solution is as follows:

  1. Read input image and make Picture1
  2. Make a Canvas and do the drawing
  3. Attach the Canvas to a Scene
  4. Make snapshot of the Scene and make WritableImage (Picture2)
  5. Compare Picture1 and Picture2

So I have a method with something like:

public static WritableImage makeDrawableImage(Canvas in) {
     AnchorPane root = new AnchorPane(in);
     WritableImage out = new WritableImage((int)in.getWidth(), (int)in.getHeight());
     Scene sc = new Scene(root, in.getWidth(), in.getHeight());

     out = in.snapshot(null, null);

     return out;
}

However it takes a really long time for the snapshot to finish. The value of out never gets assigned. I don't know what I did wrong.

Is there any alternative to convert Canvas to Image or WritableImage? Or maybe there is a library to do drawing of polygons easier with PixelWriter?

Please be soft on me. This is my first question on Stack Overflow and I'm not a real programmer nor an IT student. I code as a hobby.

So, thanks in advance. Cheers.

like image 700
Teguh Hidayat Avatar asked Apr 25 '16 06:04

Teguh Hidayat


1 Answers

You can create a snapshot of a canvas with this method:

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);     
}

The pixel scale normally is 1.0 unless you have a HiDPI screen.

like image 62
mipa Avatar answered Sep 30 '22 19:09

mipa