2

I am messing with game programming in JavaFX, and I made a spritesheet for the graphics. Currently, I am changing the JavaFX Image to a BufferedImage, then using the BufferedImage#subImage function to get a sub image, then using SwingFXUtils to change it back to a JavaFX Image. I have tried to look for an easier way but have not found one. Is their an easier way to get a JavaFX sub image?

Sheikh
  • 539
  • 1
  • 7
  • 29
  • Related: [How show specific part of an image in javafx](http://stackoverflow.com/questions/23440980/how-show-specific-part-of-an-image-in-javafx). However, the answers to the related question is based upon views or clips of images being displayed in the scene graph rather than on a canvas, so the solutions to the related question may not be directly applicable to solving this question. – jewelsea Mar 16 '16 at 22:19
  • @jewelsea I have looked that question over but I can't figure out how to implement it on a canvas. Thanks anyways. – Sheikh Mar 16 '16 at 22:21

2 Answers2

5
/*
suppose i have an image strip of 10 frames of 32x32 ( 320x32 ), then i want to separate all frames in individual images
getImage( 10, 32,32,"myStrip.png" );
*/
public static Image[] getImage( int frames, int w, int h,  String pathFile )
        {

            Image[] imgs =  new Image[ frames ];

            //img that contains all frames
            Image stripImg = new Image( pathFile );
            PixelReader pr =  stripImg.getPixelReader();
            PixelWriter pw = null;

            for( int i = 0; i < frames ; i++)
            {

                WritableImage wImg = new WritableImage( w, h );

                pw = wImg.getPixelWriter();

                for( int readY = 0 ; readY < h; readY++ )
                {

                    int ww = (w * i);
                    for( int readX = ww; readX < ww + w; readX++ )
                    {
                        //get pixel at X  & Y position
                        Color color = pr.getColor( readX, readY );

                        //set pixel to writableimage through pixel writer
                        pw.setColor(readX - ww, readY, color);

                    }//X


                }//Y


                //finally new image is stored
                imgs[ i ] = wImg;
            }//


            stripImg = null;
            pr = null;
            pw = null;

        return imgs;
        }//
Pavul Zavala
  • 427
  • 5
  • 11
4

Use the GraphicsContext::drawImage method to draw the part of the image which you wish onto the canvas.

Excerpt from the linked javadoc:

Draws the specified source rectangle of the given image 
to the given destination rectangle of the Canvas.

Parameters:
img - the image to be drawn or null.
sx - the source rectangle's X coordinate position.
sy - the source rectangle's Y coordinate position.
sw - the source rectangle's width.
sh - the source rectangle's height.
dx - the destination rectangle's X coordinate position.
dy - the destination rectangle's Y coordinate position.
dw - the destination rectangle's width.
dh - the destination rectangle's height.

The version of drawImage with a lot of parameters allows you to specify source and destination x and y co-ordinates and height and width to be used for rendering the source image onto the destination canvas (effectively allowing you to render a viewport or "subimage" of the original image).

The sample below shows the full image (of an origami bird) on the left, and the top quarter image (just the head and shoulders) of the bird draw on the right using the drawImage method.

sample

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class ImageViewportOnCanvas extends Application {
    public void start(Stage stage) {
        final Image image = new Image(IMAGE_LOC);

        final double w = image.getWidth();
        final double h = image.getWidth();

        final Canvas canvas = new Canvas(w, h);
        canvas.getGraphicsContext2D().drawImage(
                image, 0, 0, w/2, h/2, w/4, h/4, w/2, h/2
        );

        HBox layout = new HBox(
                10,
                new ImageView(image),
                canvas
        );

        Scene scene = new Scene(layout);

        stage.setScene(scene);
        stage.show();
    }

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

    private static final String IMAGE_LOC = 
        "http://icons.iconarchive.com/icons/jozef89/origami-birds/72/bird-blue-icon.png";
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • What do the parameters represent? If I have a spritesheet and I want to get the sprite at (1,1) with each sprite being 32 by 32, how would I do that? – Sheikh Mar 16 '16 at 22:56
  • Updated question with a copy and paste of text from the linked javadoc for your convenience. – jewelsea Mar 16 '16 at 22:59
  • Just curious.. Is there any way I can save the sub image to a variable? – Sheikh Mar 16 '16 at 23:07
  • Yes there is, via a PixelReader/Writer and a WritableImage. Or using node snapshots on an ImageView. But I won't write up solutions for those approaches right now. – jewelsea Mar 16 '16 at 23:10
  • OK, I think I can handle that. Thanks a ton! – Sheikh Mar 16 '16 at 23:11