2

I need to fit a huge image (BufferedImage to access colors etc) into a JScrollPane derived class. Nothing very hard until there.

The image is a JPG scan of an A3 sample of material, its size is 13030x20840 pixels, 24bits, and weights 12MB on disk -> about 800MB in RAM.

I embedded the BufferedImage into a Jpanel, which lies as the Scrollpane's view.

When I try to scroll/drag my image, it takes seconds to respond, so it is not very handy.

I need your help in order to know what I should do to render the scrollpane's scrolling and the image dragging as smooth and reactive as possible, but I easily figure out that with such an image it could be impossible.

I tried many options, such as double buffering, etc. but I'm quite new to Swing, then it is greatly possible I missed some simple solution.

If there is a need to change the BufferedImage by something else, or whatever, I'm receptive to any solution.

Benj
  • 1,184
  • 7
  • 26
  • 57
  • 2
    An image that size is about 750MB, not 12 MB, after it's been uncompressed into an image buffer. – Jim Garrison Nov 14 '12 at 19:59
  • @Jim Garrisson : exact, I rewrite it. Thanks for paying attention to this detail. – Benj Nov 14 '12 at 20:01
  • 1
    Break your image up into tiles. 256 pixel x 256 pixel tiles are common. Display only the tiles that fit in the scroll pane. When the scroll pane sliders are moved, show the different tiles. – Gilbert Le Blanc Nov 14 '12 at 20:05
  • I already did that into a previous try, but it was in a different programming language. I don't really figure out how to put the tiles in the scrollpane -> layout ? – Benj Nov 14 '12 at 20:09
  • You build a buffered image from the tiles, and display the buffered image as you're doing now. The only trick is to build a new buffered image when the user scrolls and position that new buffered image correctly in the scroll pane. – Gilbert Le Blanc Nov 14 '12 at 20:18
  • Okay, I will try this, thanks ! I keep being receptive to any solution. – Benj Nov 14 '12 at 20:20
  • I just wondered : is it not possible to partially load/display the image from the whole image object ? I will try both ways, but stop me if I'm doing it wrong. – Benj Nov 14 '12 at 20:25
  • [see idea by @Gilbert Le Blanc](http://stackoverflow.com/questions/11330268/how-to-smoothen-scrolling-of-jframe-in-java/11330436#11330436), there are a few questions with real answers how to split one image to the few parts (puzzle e.i.) – mKorbel Nov 14 '12 at 20:54
  • @mKorbel : indeed, there are a lot... I was wondering and surfing the doc to find how to make the scrolls "wider" than the viewport's contents. – Benj Nov 14 '12 at 20:56
  • my question is for why reason you required to dipslay so huge Image, for post processing, zooming you needed PC designated for CAD/CAM ..., – mKorbel Nov 14 '12 at 20:57
  • I need to measure a lot of things on wood samples (tree rings, cells diameters, etc). The wood samples are prepared to be put on a scanner with a scale (generally a precision ruler), then I can work on the image of a lot of samples scanned in one time instead of behind binoculars one sample at a time, which is very very very time-spending. – Benj Nov 14 '12 at 21:01
  • you'll need working with pretty (don't forget) asynchronous getScalledInstance, – mKorbel Nov 14 '12 at 21:01
  • @mKorbel : thanks, I 'm opening the doc of this. I will post later what it brought to my problem. – Benj Nov 14 '12 at 21:02
  • for preview to use scalled instance to A4, maybe you'll be to able to see some (maybe the same) defect in 1/4 ratios in compare with A3, brrrr :-) – mKorbel Nov 14 '12 at 21:05
  • @mKorbel : sorry, impossible. Often I need to zoom on... pretty heavy for the CPU to do an AffineTransform on the huge image to zoom it... I'm currently trying a mix of your idea and Gilbert Le Blanc's : displaying a dynamically generated part of the image, and I use te scrolls in an unusual way as "scroll speed" "cursors". – Benj Nov 14 '12 at 21:45

2 Answers2

2

So, we have a large 13,030 x 20,840 pixel image.

if we break this image into 256 x 256 pixel tiles, we get a tile set that's 51 tiles across and 82 tiles down. The last tiles in the rows and columns will be partial images, since 256 doesn't go evenly into 13,030 and 20,840.

Let's assume our display window is 400 X 400 pixels. Let's also assume were starting in the upper left hand corner of the large image.

We take and make a 3 x 3 tile buffered image. This would be 768 x 768 pixels, which allows enough overlap for smooth scrolling. We take the first 3 tiles from the first row, the first 3 tiles from the second row, and the first 3 tiles from the third row to make our 3 x 3 tile buffered image.

Now, when we set up the horizontal and vertical scroll on the JScrollPane, we have to set the maximum value on the horizontal scroll to 13,030 and the maximum value on the vertical scroll to 20,840. This is so the user is kinetically aware that he is scrolling a large image.

Ok, we display the 3 x 3 tile buffered image. The user scrolls to the right to see more images. The user has scrolled 256 pixels.

The application now has to build a new 3 x 3 tile buffered image. We take the 2nd through 4th tiles from the first row, second row, and third row. We display this new buffered image. To the user, it looks like one huge image. To the application, a series of small 3 x 3 tile buffered images are displayed.

mKorbel has already created some code which builds and displays these smaller buffered images on the fly.

To deal with zooming, you can resize the large image outside of the Java application and create more than one tile set. This makes the Java application code more complicated, but much faster than trying to resize the smaller buffered images in the Java application.

Community
  • 1
  • 1
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • Yay ! Thanks for the link, I did not find it out -> my browser does not hilite it (in your previous comment) for some obscure reason... Many thanks to you and mKorbel ! – Benj Nov 15 '12 at 23:02
  • mKorbel's great Solution implemented [[http://stackoverflow.com/questions/11330268/how-to-smoothen-scrolling-of-jframe-in-java/11330436]], re-thanks to you and him ! I coupled his solution with an array of WeakReference to store the individual tiles without hard mermory persistence. It's all OK. – Benj Nov 18 '12 at 15:44
  • See this : http://www.informit.com/articles/article.aspx?p=23668&seqNum=10 , very interesting. – Benj Apr 13 '13 at 23:07
0

I found what I needed there :

very large image manipulation and tiling

A nice book, the sample shown covers that.

The Java JAI lib has a lot of features to handle these kind of problems, and is supported by Oracle, which means it is (theoretically) stable and sustainable.

Thanks to @BryanD !

Community
  • 1
  • 1
Benj
  • 1,184
  • 7
  • 26
  • 57