Effective image cropping in JavaFX


I'm trying to write a Jigsaw puzzle using JavaFX partly because someone asked me and partly because I want to give JavaFX a go. However, I am having difficulty with the actual cropping of the image.

The idea is for the user to supply the image and the program to cut the image into smaller pieces. Simple, right? My problem is this: The only way I could find to cut the image is to make a copy of the image object and change the visible part of the copy, here's an example:

ImageView imgageView = new ImageView(); // Creates a new ImageView; this will be a single puzzle piece.
imgageView.setImage(originalImage); // Use the original image as the "base."
Rectangle2D rectangle = new Rectangle2D(0, 0, 50, 50); // Crop the image from (0,0) to (50, 50).

Just to clarify the last line, here's the related piece in the API:

public Rectangle2D(double minX,
           double minY,
           double width,
           double height)
Creates a new instance of Rectangle2D.
minX - The x coordinate of the upper-left corner of the Rectangle2D
minY - The y coordinate of the upper-left corner of the Rectangle2D
width - The width of the Rectangle2D
height - The height of the Rectangle2D

Now this is fine if I'm cutting the picture into four or nine pieces (the game is meant for young children), but what if I want to cut the picture into a nice 1200 piece puzzle? Will this not result in an extremely expensive operation? Not only the cropping itself, but to keep that many copies of the image in memory. See, if I'm understanding this correctly each piece will consist of the entire original image with a large portion of it that will remain "hidden."

Am I simply misunderstanding the function? If not, there must be a better way to do this, right?

8/11/2014 3:12:45 PM

Accepted Answer

Using PixelReader and WritableImage should help.

the following cuts a new image from an old one at position (x,y) and size (width, height)

PixelReader reader = oldImage.getPixelReader();
WritableImage newImage = new WritableImage(reader, x, y, width, height);
10/30/2014 4:57:09 PM

Multiple ImageView objects can reference the same Image. The data for the image itself is stored in the Image. If you have 1000 ImageView objects each referencing the same Image then there is only 1 copy of the pixels in memory. Creating copies using WriteableImage would actually be more expensive than having multiple ImageView objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow