createImage on large jpegs fails

Started by
9 comments, last by ross_w 18 years ago
Hi guys! I am trying to make an image viewer midlet because this native image viewer in my L6 sucks (and i have heard that on V3 it is the same). So I a have made a code which browses through the image folder, gets the image list, gets the image, resizes it if it is needed to fit the screen and displays the images on the Canvas. To get an image i am first loading the content of the file into byte[] array and than I call the function createImage(byte[] array) to create an Image object. This object I than rotate and resize if needed. It works well on all images except on jpeg images taken with the camera. What is strange is that it does not throw any exception. It just does nothing. When I put the alert immediately after the createImage method it is not displayed at all! Like if it just jumps out from the procedure. Strange. I suppose that larger images are the problem.... Also do You know how to display animated gifs in the Canvas? When I draw the image it just creates the first frame. Best regards, ross
Advertisement
I don't know about the jpegs, it could be a size problem. What size are we talking about? Any problems with smaller jpegs (it's possible that the format simply isn't supported)? Maybe if you post some code we might spot some errors.

Quote:Original post by ross_w
Also do You know how to display animated gifs in the Canvas? When I draw the image it just creates the first frame.

MIDP doesn't have any support for animated gifs. You would need to animate them on your own: parsing all of the frames out of the original and running a thread that animates them as necessary.

shmoove
No - smaller jpg's are fine. I.e. 352x288 are loading fine, but 640x480 are not...
Here is the code snippet:

private boolean getImage( int index ) {
FileConnection fconn = null;
InputStream is = null;
try {
fconn = (FileConnection)Connector.open( baseFolder + (String)files[ index ], Connector.READ );
if (!fconn.exists())
throw new IOException("File: " + (String)files[ index ] + " does not exist");
is = fconn.openInputStream();

byte[] b = new byte[ (int)fconn.fileSize() ];
int n = is.read( b );

//this alert is shown allways - array is loaded fine in all cases:
// alert( String.valueOf( n )+ " bytes read.", AlertType.INFO );
myImage = Image.createImage( b, 0, n );

// instead of loading first into array here can be also:
// myImage = Image.createImage( is );

// but when image is too large this alert is not shown at all:
// alert( "Image created", AlertType.INFO );
is.close();
fconn.close();
imgWidth = myImage.getWidth();
imgHeight = myImage.getHeight();

} catch (Exception e) {
// when image is too large this one is not shown too:
alert( e.toString(), AlertType.ERROR );
if ( is != null )
try{ is.close(); } catch(Exception ex){}
if ( fconn != null && fconn.isOpen() )
try{ fconn.close(); } catch(Exception ex){}
if ( myDisplay != null )
AlertType.ERROR.playSound( myDisplay );
System.out.println(e);
e.printStackTrace();
return false;
}
return true;
}
640x480 is quite big. Are you able to load pictures that size in any other format? It could be that you are simply running out of memory (MIDlets have a tendency to start acting quirky when that happens). How big is the heap on your phone? Remember that most implementations will expand the image when it's loaded so it takes [# of pixels]*[bytes per pixel] bytes in the heap.

I can't see anything inherently wrong with your code (but I would check to make sure that the file size and the number of bytes read from the input stream are the same).

shmoove
I haven't tryed to load such large pictures of other formats yet. I'll check it.
I was thinking about the memory problem, but I have expected some exception to be thrown in the case of the insufficient memory.
I do not know about the heap size - how do I check the size of the heap? I only know that entire free memory is about 6Mb.
I've checked file size and the number of bytes read from the input stream - they are the same.
Quote:I have expected some exception to be thrown in the case of the insufficient memory.


In my experience, when cell phones run out of memory, they have undefined behavior; sometimes they will crash the application and return it to the OEM screens, sometimes you will get an alert or pop up message stating out of memory, other times the application will hang there and do nothing.

To check the heapsize...do this:

long TotalMem = Runtime.getRuntime().totalMemory();

Hope that helps!
---"The problem with problems is that there are always too many"
it may be possible that you phone has video memory. running out of video memory is not signaled as with running out of heap (outofmemory exception). not to mention the fact that some phones will not allocate you image data in the heap in case of not enough video memory...
Quote:Original post by ross_w
I have expected


Expectations have no place in cellphone development.

shmoove
So I've checked the memory, and here is what i've got:
Total mem. available to the midlet is 803480 bytes. I checked also free mem. before and after successfull createImage command:
- the free mem before loading was around 680000 bytes or less
- for 128*160 image, memory consumption was 38680 bytes (ratio ~1,89)
- for 352*288 image, memory consumption was 203032 bytes (ratio ~2)
I do not know how exactly how the image is coded co I can't calculate exactly the memory consumption for the 640*480 image, but if it is 2bytes per pixel than memory needed for creating such an image would be more than 600000 bytes which is a little bit les than the free mem so it is possible that the mem is not enough... :-(
So, now question is if there is a way how to resize the jpeg without first creating an image... I suppose that I woud have to make some encoding routine and encode and resize it on the fly... :-( I wonder how the image explorer inside the phone is doing it...
Any resizing would still need an array for the pixel data, but I guess you could use pallette indexes instead of true colors for every pixel thus saving one or three byte per pixel. It would certainly be quite slow.

Here's a png decoding routine in any case.

shmoove

This topic is closed to new replies.

Advertisement