Solved

java.lang.OutOfMemoryError with jai

Posted on 2004-08-23
12
708 Views
Last Modified: 2008-02-01
I am loading an image into a renderedOP from a cgi call and udating it based on manipulation inputs (rotate, scale, etc).  After about 3 rotations, the system crashes with an outofmemory error.  This app wil eventually become an applet, so compiling with a larger vm memory size probably won't work as I've seen in other forums.  Those forums also suggest using JAI, but I already am and can't figure out how to avoid the error.
0
Comment
Question by:tigress298
  • 4
  • 3
  • 3
12 Comments
 
LVL 35

Expert Comment

by:TimYates
ID: 11872625
how big is the image?

can you post some code?
0
 

Author Comment

by:tigress298
ID: 11872781
The images are pretty large (about 30,000 pixels length and height each, for the full res image), but I don't know the exact sizes.  The user selects the res.

The code is a bit obfuscated, and I can't give the address of the actual images, but basicall I set up a query string in chipQuery() which I access from showChip() and create the image.  

public void showChip() {
        if (canvas.isVisible() == true) {
            String query = chipQuery();
            java.net.URL url;
            try {
                canvas.getDesktop().getMsgCenter().getMessageArea().setText(
                canvas.getDesktop().getMsgCenter().getMessageArea().getText() +
                "\nAccessing: "+ query);
                url = new java.net.URL(query);
            }
            catch (Exception e) {
                url = null;
                e.printStackTrace();
            }            
            if (url != null) {
                //canvas.getChip().setIcon(new javax.swing.ImageIcon(url));
                currentImage = null;
                currentImage = JAI.create("url", url);
                canvas.getChip().setIcon(new javax.swing.ImageIcon(
                    currentImage.getAsBufferedImage().getScaledInstance(
                    currentImage.getWidth(), currentImage.getHeight(), 0)));
            }
        }
    }

on rotation, which ultimately spawns the error, I set the rotation value in rotate(), and setup the parameter block for rotation in rotateChip()

 public void rotate(int angle) {
        int newAngle = angle;
        if (newAngle != currentRotation) {
            int difference = newAngle - currentRotation;
            rotateChip(difference);
            currentRotation = newAngle;
        }
    }

private void rotateChip(int angle) {
        if (canvas.isVisible() == true) {
            RenderedOp image;
            ParameterBlock pb = new ParameterBlock();
            pb.addSource(currentImage);
            pb.add((float)referencePoint.x);
            pb.add((float)referencePoint.y);
            pb.add((float)Math.toRadians((double)angle));
            pb.add(new InterpolationBilinear());
            image = JAI.create("Rotate", pb, null);
            canvas.getChip().setIcon(new javax.swing.ImageIcon(
                image.getAsBufferedImage().getScaledInstance(
                image.getWidth(), image.getHeight(), 0)));
            currentImage = image;
        }
    }  


Thanks.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11872852
Could be simply too much to handle if it's too big. Why not try creating tiles of the image and rotating the tiles sequentially? That way you can reduce memory footprint and still get the result you need
0
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 
LVL 35

Expert Comment

by:TimYates
ID: 11872885
I'm guessing it's the:

canvas.getChip().setIcon(new javax.swing.ImageIcon(
                image.getAsBufferedImage().getScaledInstance(
                image.getWidth(), image.getHeight(), 0)));

line which throws the exception?

Hmmm...  I *think* you will have to do this by overriding the paintComponent on a JPanel (instead of setting the image as an Icon to a JLabel), and only draw the area that you can see, by using AffineTransform on the Graphics2D object that you get in that function...  

That way, you won't be creating a new Image object each time you do a transformation...

That might help anyway...  I'm not at work at the moment, so I can't dig out much code, but here are some links that may be of some help:

http://javaalmanac.com/egs/java.awt.image/CreateTxImage.html
http://javaalmanac.com/egs/java.awt/TransformImage.html

Remember, override paintComponent (for a JPanel), not paint...

Tim
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11872907
So, as (I think) CEHJ is saying, you will end up with a "stack" of transformations, and your original image...  Before you draw the image, add this stack of AffineTransforms to the Graphics2D object sequentially, then simply draw the image as normal...

Then you only create the image once (when you load it)
0
 
LVL 35

Accepted Solution

by:
TimYates earned 250 total points
ID: 11872911
You may *still* have problems getting an image that big into an applet though...
0
 

Author Comment

by:tigress298
ID: 11873054
How would I go about tiling the image?  

Also, the cgi call is based off the current viewer veriosn (java 1.1) which I'm revamping.  The current call includes among other things, the resLevel, the currentMode(rotate, scale, etc), a reference point (distance from the center of the image for translation), the dimensions of the expected image at the current resLevel, the viewable size (512 or 1024), and the rotation angle.  The cgi handled the image manipulation server side and passed back the image, but is VERY slow, so I'm having a hard time knowing what info to handle inside the applet with JAI, and what to let the server handle (and how to keep the differences reconciled).  Otherwise, loading the image once and handling all manipulations with JAI would be optimal.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11873070
What i meant was rather than going straight from (using e.g. 180 degree rotation)

¡ ¡ ¡ ¡
¡ ¡ ¡ ¡

to

! ! ! !
! ! ! !

tile and go in steps, reassembling

1.

! ¡ ¡ ¡
¡ ¡ ¡ ¡

2.

! ! ¡ ¡
¡ ¡ ¡ ¡

etc.
0
 

Author Comment

by:tigress298
ID: 11873116
I stil don't know how to go about doing that, though I understand what you're doing.
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 250 total points
ID: 11873160
Well i don't know JAI but i'd guess it'd have an easy method for tiling an image and you could always fall back on

http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/BufferedImage.html#getSubimage(int, int, int, int)
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question