Core Java

JavaFX ImageView Example

1. Introduction

JavaFX exposes easy-to-use API for painting images on its stage via the javafx.scene.image.ImageView class. An instance of ImageView class does not merely renders images loaded instance of javafx.scene.image.Image class, but also provides a variety of flexible manipulations to control various aspects of image rendering; in this post we are going to have a look at them. We would be using JavaFX API version 8 from JDK 8.

2. First Things First: Load the Image

Any image that has to be rendered on a JavaFX stage must be first loaded into memory. The in-memory representation of any image is, as mentioned earlier, is through an instance of the Image class. There are a variety of easy ways for loading an image via the Image class, however, there is a caveat: not all images can be represented in-memory via the Image instance; only BMP, GIF, JPEG, PNG are valid formats as of now.

Following are two of the most frequently used mechanisms of loading an image via the Image class:

2.1 InputStream

The Image class has a variety of overloaded public constructors, one of them takes an InputStream as an argument. And thus any InputStream which represents a valid image can be passed to this constructor for loading that particular image. Following code snippet illustrates this idiom:

FileInputStream imageStream = new FileInputStream("/path/to/the/image");
Image image = new Image (imageStream );

Note that this constructor can potentially throw a NullPointerException if the passed InputStream is null; consequently, the calling method should take proper care of either handling this exception or re-throwing it further into the method call stack.

Nevertheless, once the constructor successfully executes, we would have the image loaded into memory for rendering onto the JavaFX stage.

2.2 url

The Image class has another public single argument constructor which takes a String url.

public Image(String url)

The very fact that we can directly pass an url gives us the flexibility not just to load image from a local file system but also to point to an image exposed on some network via its url; please follow the following code snippets for illustrations:

Image imageOnLocalFileSystem = new Image("/path/to/the/image/on/filesystem");
Image imageOnNetwork = new Image("http://www.imgion.com/images/01/Voilet-Flower-.jpg");

It is noteworthy that this constructor may throw NullPointerException when the url is null; it may also throw IllegalArgumentException when url is invalid or unsupported.

Note that ImageView class also has a dedicated constructor which takes a String url pointing to the image:

public ImageView(String url)

We would demonstrate this approach as well in the final demonstrative application but note that using this approach does not reduce the need of an Image instance because the run time does create an Image instance based on the url passed by us. What is achieved using this approach is that the burden of instantiating the Image class is deferred to the JavaFX run time. Internally this is what happens:

public ImageView(String url) {
this(new Image(url));
}

This constructor also throws exceptions which must be handled by the callers.

3. Load ImageView with Image

Once an image is successfully loaded, all that is required is to initialize or set the ImageView.image property which is of type ObjectProperty<Image> and there are publicly exposed APIs for doing this, consider the following demonstrations:

3.1 Initialize ImageView.image

ImageView.image can be initialized during ImageView instance construction itself by passing relevant Image instance. Consider the following ImageView constructor:

 public ImageView(Image image) 

3.2 Set Image via relevant Setter method

If Image instance cannot be passed during ImageView instance creation, ImageView.image can still be set using the following method call on ImageView instance:

public final void setImage(Image value)

4. Time to render Image

Once ImageView.image has been successfully initialized, ImageView can be associated with the Scene graph. Note that ImageView is-a javafx.scene.Node and therefore, an ImageView instance can be set as a “child” to a javafx.scene.layout.Pane, let us say:

Image image = new Image(String url);
ImageView imageView = new ImageView (image);
HBox hbox = new HBox();
hbox.getChildren().add(imageView );
Scene scene = new Scene(hbox);

5. Other Flexibilities

The ImageView class does not just render your image, but it also provides a whole lot of other functionalities for common use-cases. In the subsequent sub-sections we would go through them:

5.1 Image resizing with/without preserving the aspect ratio

ImageView class has the following two methods which could be used to “fit” the image inside the given dimensions of width and height:

public final void setFitWidth(double value)
public final void setFitHeight(double value)

However, note that changing any of these dimensions does not guarantee that the JavaFX runtime would honor the aspect ratio of the image! To maintain the aspect ratio while changing any or both of these dimensions, we must explicitly set the ImageView attribute preserveRatio as true using the following method call:

public final void setPreserveRatio(boolean value)

5.2 Setting Viewport

ImageView class also provides functionality to provide a “Viewport” into the image. We may understand viewport as a window through which we may be viewing the image and thus, the dimensions of the viewport would dictate the area of the original image visible. In other words, viewport would mask every other area of the image exposing only that area which corresponds to the position and dimensions of the viewport. The related APIs are as follows:

ObjectProperty<Rectangle2D> viewport
public final void setViewport(Rectangle2D value)

Following is the code snippet which uses the above API:

Rectangle2D viewPort = new Rectangle2D(10, 20, 50, 60);
ImageView imageView = new ImageView (someImage);
imageView.setViewport(viewPort);

Effectively what this means is that we would be creating a viewport window beginning at coordinate (10, 20) and of dimensions 50×60 on the image for its visibility.

5.3 ImageView Transformations

Remember in section 4 we mentioned that ImageView is-a Node, and therefore ImageView inherits all the members from the Node class including the transformation functions. This means that the before final rendering, the image could be transformed as per application requirements. Following is one example of such a transformation:

ImageView imageView = new ImageView (someImage);
imageView.setRotate(50);

The above code snippet would rotate someImage 50 degrees clockwise.

6. Bringing All Bits Together

We have discussed quite a few APIs from the Image and ImageView class, now it is time to bring all of them together in a demonstrative application:

ImageViewExample.java

package imageviewexample;
	
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

/**
 * 
 * @author NawazishMohammad
 * 	ImageViewExample demonstrates the various ways of loading an image 
 *  and rendering the same on the JavaFX stage.It also demonstrates the 
 *  various functionalities that ImageView class has to offer for image rendering.
 */
public class ImageViewExample extends Application {
	@Override
	public void start(Stage primaryStage) {
		/**
		 * In the following example image is assumed to be present 
		 * in a directory on the application class path
		 */
		Image image = new Image("imageresource/Yellow-Vector-Flower-.jpg");		
		/**
		 * imageView1 takes image and manipulates it size,
		 * and preserves its aspect ratio
		 */
		ImageView imageView1 = new ImageView(image);
			imageView1.setFitHeight(100);
			imageView1.setPreserveRatio(true);
		
		/**
		 * imageView2 manipulates the width of the image, 
		 * preserves the aspect ratio and rotates the image by 90 degrees
		 */
		ImageView imageView2 = new ImageView(image);
			imageView2.setFitWidth(200);
			imageView2.setPreserveRatio(true);
			imageView2.setRotate(90);
		
		/**
		 * We set a viewport on imageView3 creating an illusion of zoom-in effect
		 */
		Rectangle2D viewPort = new Rectangle2D(925, 50, 600, 600);
		ImageView imageView3 = new ImageView(image);
			imageView3.setFitWidth(100);
			imageView3.setPreserveRatio(true);
			imageView3.setViewport(viewPort);
		
		/**
		 * imageView4 receives its image from a public url
		 */
		String flowerImageStr = "http://www.imgion.com/images/01/Voilet-Flower-.jpg";
		Image flowerImage = new Image(flowerImageStr);	
		ImageView imageView4 = new ImageView(flowerImage);
			imageView4.setFitWidth(200);
			imageView4.setPreserveRatio(true);
		
		/**
		 * imageView5 demonstrates setting ImageView.image using the JavaFX's Property API
		 */
		ImageView imageView5 = new ImageView();
			imageView5.imageProperty().set(image);
			imageView5.setFitWidth(200);
			imageView5.setPreserveRatio(true);
			imageView5.setRotate(-90);
			
		/**
		 * imageView6 directly points to the url of the image-
		 * obviating the need for an Image class instantiation
		 */
		String imgUrl = "http://www.imgion.com/images/01/Voilet-Flower-.jpg";
		ImageView imageView6 = new ImageView(imgUrl);
			imageView6.setFitWidth(200);
			imageView6.setFitHeight(200);
			imageView6.setPreserveRatio(true);
			
		HBox hbox = new HBox(10);
			hbox.getChildren().addAll(imageView1,imageView2,
						imageView3,imageView4, 
						imageView5,imageView6);
			
		Scene scene = new Scene(hbox);
		primaryStage.setScene(scene);
		primaryStage.show();
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

ImageView Example
ImageView Example

7. Conclusion

JavaFX’s Image and ImageView classes provide an easy to use API for rendering images on JavaFX stage. It is as easy as pointing to your image via the Image instance and then handing it over the ImageView instance for painting. Besides plain-vanilla painting, ImageView also offers you to transform the images as per requirements.

8. Download The Eclipse Project

This was an example about rendering images on JavaFX stage using ImageView and Image APIs.

Download
You can download the entire Eclipse project here: ImageViewExample

Nawazish Khan

I am Nawazish, graduated in Electrical Engineering, in 2007. I work as a Senior Software Engineer with GlobalLogic India Ltd (Banglore) in the Telecom/Surveillance domain. A Java Community Process (JCP) member with an unconditional love (platform, technology, language, environment etc does not matter) for computer programming. Extremely interested programming multi-threaded applications, IoT devices (on top of JavaME) and application containers. The latest language of interest being Google Go; and Neo4j as the NoSQL Graph Database solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button