Solved

java.lang.OutOfMemoryError with jai

Posted on 2004-08-23
12
711 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 
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

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

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

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.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
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 …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

688 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