Summary
Among the most significant Java 6 improvements addressed graphics and UI performance. With a several-fold speedup of many JDK graphics operations, desktop Java is well-suited for high-performance image manipulation and viewing, as Slav Boleslawski's java.net article on a navigable image panel illustrates.
Advertisement
As high-resolutions digital cameras churn out increasingly bigger images, scaling an image is often the only way to present a digital photo in its entirety on the screen.
As Slav Boleslawski demonstrates in his recent java.net article, A Navigable Image Panel, the Java2D API offers many features supporting image scaling. Indeed, achieving a high level of usability in an application requires that a developer become familiar with all the relevant image scaling API elements and their combinations.
Boleslawski demonstrates how to combine Java2D's three algorithms supporting image scaling to achieve smooth zooming and un-zooming effects in an image viewing panel:
Some sort of interpolation/decimation is required to increase/decrease the number of pixels to display the image for a given zoom level.
There are three possible interpolation algorithms available in Java 5, each requiring different computational times and producing results of different quality. The default interpolation is nearest neighbor. Whenever an image is drawn on the screen using Graphics.drawImage() method, the nearest neighbor interpolation is applied by default, which produces the fastest rendering and acceptable quality. The quality is quite good up to a given zoom level. Beyond that level, pixelation effects become visible and lines and boundaries become jagged...
Bilinear interpolation is more time intensive, but produces better results... Bicubic interpolation requires even more computational time and its rendering quality is the best of the three interpolation methods...
Rendering time is proportional to the number of pixels to be interpolated. When we zoom in, we decrease the number of pixels in the original image that need to be interpolated in order to fill up the screen. We could start with the nearest neighbor interpolation initially, and then switch to bilinear interpolation when the number of pixels to be processed is small enough to ensure an acceptable speed of rendering.
Boleslawski provides detailed code examples of how to achieve the combination of scaling algorithms to create the highest usability in the application. While his examples work on JDK 5, running the examples on JDK 6 yields even better performance and a few additional API enhancement to affect faster scaling operations, according to the article.
In addition to scaling, the presence of large images requires that the application does not keep an entire high-resolution image in memory, and instead uses the ImageIO API's subsampling methods, storing only the minimum amount of image data in memory.
What are the biggest challenges you encounter when viewing and manipulating images with Java2D? What do you think of Boleslawski's solution of switching scaling algorithms based on image size?
In the project I am working, Java image scaling is so slow when I use the smooth method, that I had to pre-smooth all images using a separate program, then use plain scaling from Java. And this on a Pentium 4 at 1.6 GHz with 1 GB memory but with a lame graphics card (images' size was 1024x768, true color).