J2ME displaying an image file

Hello,

Anyone can help me to create a program that can display a jpeg file ? As simplest as possible :)

Thank you
tambunAsked:
Who is Participating?
 
OBCTCommented:
Ahhh I seemed to have missed this one...

In your run() method, you've made a call directly to the Image classes createImage() rather than your own implementation.
The Image.createImage() method attempts to load an image from the application's resources rather than from a HttpConnection.

Try this as your run method, then we'll take it from there.

public void run()
{
    Image theimage = null;
    String name = "http://127.0.0.1:11001/image.jpg";  
   
    try
    {
        theimage = createImage(name); // Call createImage from this class to load the image via a HttpConnection
    }
    catch (IOException err)
    {
        err.printStackTrace();
    }

    frame.setImages(theimage);
    display.setCurrent(frame);
}
0
 
OBCTCommented:
It's against the EE regulations to write code for you however you should look into javax.microedition.lcdui.Image and javax.microedition.lcdui.ImageItem.
At the moment the only images supported are of a PNG format...hopfully there will be more support in the furture. More information is in the documentation.
For your application you'll need a form to hold the ImageItem or the other option is to display the Image in a canvas.

If you have any other questions, let me know. :-)

Cheers

-OBCT
0
 
tambunAuthor Commented:
Thanks for your information. Is that true that the only image format supported is PNG ? Because I run the "photoalbum" demo application from J2ME Wireless Toolkit 2.1, it can display JPEG without any problem.

My case is, I would like to display an image from http. This image will be changed periodically by the web server.
So, as long as I can grab and display http://127.0.0.1:11001/image.jpg, problem solved.

Here is my code, but it does not produce anything :( Maybe you could see if I made some mistakes.

package jpgmidlet;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.Vector;
import java.io.IOException;
import java.io.DataInputStream;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.Connector;

public class JpgMidlet extends MIDlet implements Runnable
{
   private Display display;
   private Thread thread;
   private Frame frame;

   public JpgMidlet() {  
      display = Display.getDisplay(this);

      frame = new Frame();
   }

   protected void startApp() {
      run();
   }

   protected void pauseApp() {
   }

   protected void destroyApp(boolean unconditional) {
   }

   private Image createImage(String name) throws IOException {

       // Load from a ContentConnection
       HttpConnection c = null;
       DataInputStream is = null;
           
       try {
          c = (HttpConnection)Connector.open(name);
          int status = c.getResponseCode();
       
          if (status != 200) {
             throw new IOException("HTTP Response Code = " + status);
          }

          int len = (int)c.getLength();
          String type = c.getType();

          if (len > 0) {
              is = c.openDataInputStream();
              byte[] data = new byte[len];
              is.readFully(data);
              return Image.createImage(data, 0, len);
          } else {
              throw new IOException("Content length is missing");
          }

      } finally {
            if (is != null)
             is.close();

          if (c != null)
             c.close();
       }

   }


   public void run() {
      Image theimage = null;

      String name = "http://127.0.0.1:11001/image.jpg";  
      try {
         theimage = Image.createImage(name);
      } catch (IOException err) {
      }

      frame.setImages(theimage);
      display.setCurrent(frame);

   }
}

class Frame extends Canvas {

    private Image image;

    Frame() {
       image = Image.createImage(getWidth(), getHeight());
    }

    void setImages(Image theimage) {
       Image image = theimage;  
    }

    protected void paint(Graphics g) {
       g.drawImage(image, 0, 0, Graphics.LEFT|Graphics.TOP);
    }

}
0
On-Demand: Securing Your Wi-Fi for Summer Travel

Traveling this summer?Check out our on-demand webinar to learn about the importance of Wi-Fi security and 3 easy measures you can start taking immediately to protect your private data while using public Wi-Fi. Follow us today to learn more!

 
OBCTCommented:
Just taking a quick look at the code, I can only see one problem and it's a common one so no need to feel silly :-).

You have implemented the Runnable interface and added the Run method which is all fine.
In the startApp() method you've called the run() method directly. By doing this, the startApp() method will not return until the run() method has returned rather than letting the thread run while the MIDlet continues to execute.

The correct way to do this is to use the instance of Thread (which you have in your class variables), then specify the Runnable target.
Seeing as the MIDlet has implemented the Runnable interface, you can use "this" as the target because the current instance implements Runnable.

e.g. thread = new Thread(this);

What this is doing is telling the Thread class that there is a run() method in your MIDlet and when the thread runs, the run() method will be called.
To start the thread, you MUST call thread.start().
This registers the Thread with the ThreadMonitor inside the VM which will take care of the rest for you.

I hope this makes sense.

http://java.sun.com/docs/books/tutorial/essential/threads/
Here is a much more detailed explanation of Java and Threads. It will cover just about everything you will ever need to know about them.

http://developers.sun.com/techtopics/mobility/midp/articles/threading2/
This article is more relevant to the platform you are working with.

As for the PNG format for Images, I tripple checked the documentation and MIDP will only support PNG.
Here's what the doc says...

PNG Image Format
Implementations are required to support images stored in the PNG format, as specified by the PNG (Portable Network Graphics) Specification, Version 1.0. All conforming MIDP implementations are also conformant to the minimum set of requirements given by the PNG Specification. MIDP implementations also must conform to additional requirements given here with respect to handling of PNG images. Note that the requirements listed here take precedence over any conflicting recommendations given in the PNG Specification.

createImage
public static Image createImage(byte[] imageData, int imageOffset, int imageLength)
Creates an immutable image which is decoded from the data stored in the specified byte array at the specified offset and length. The data must be in a self-identifying image file format supported by the implementation, such as PNG.

So the image being in a JPG format is bound to cause problems.
Although the WTK may load JPG images, a real phone may cause totally different results.
Emulators a great, however MIDP applications will always perform differently on real phones.

Cheers :-)

-OBCT
0
 
tambunAuthor Commented:
I tried to do that in the startApp() :

   thread = new Thread(this);
   thread.start();

But still, it does not produce anything. I made this source code based on the "photoalbum" demo of WTK2.1 which is run perfect.

Is there any way to display a message for debugging purposes ?

Displaying thing in the J2ME is difficult concept for me :(
0
 
OBCTCommented:
Change your run() method to the following...

public void run()
{
    Image theimage = null;
    String name = "http://127.0.0.1:11001/image.jpg";  
   
    try
    {
        theimage = Image.createImage(name);
    }
    catch (IOException err)
    {
        err.printStackTrace();
    }

    frame.setImages(theimage);
    display.setCurrent(frame);
}

The method is very similar except if an exception occurs, the stack will be dumped into the console so you can track down the error.
If an exception is thrown, post the stack trace.

Apart from all I have specified, I can't really see any problem at all.
Have you tried this on a real phone? If so, did the MIDlet display anything?
0
 
tambunAuthor Commented:
Here is the stack report

java.io.IOException
      at javax.microedition.lcdui.ImmutableImage.getImageFromStream(+15)
      at javax.microedition.lcdui.ImmutableImage.<init>(+20)
      at javax.microedition.lcdui.Image.createImage(+8)
      at jpgmidlet.JpgMidlet.run(+31)
0
 
tambunAuthor Commented:
I still got the exception :

java.io.IOException
     at javax.microedition.lcdui.ImmutableImage.getImageFromStream(+15)
     at javax.microedition.lcdui.ImmutableImage.<init>(+20)
     at javax.microedition.lcdui.Image.createImage(+8)
     at jpgmidlet.JpgMidlet.run(+33)  
0
 
tambunAuthor Commented:
Ok my mistake, sorry.

I dont get any exception.

But still no display ...

I think the problem is now displaying theimage.
0
 
tambunAuthor Commented:
Finally, I got the display !

By changing to this in the Frame() class :

    void setImages(Image theimage) {
       image = theimage;  
    }

But I think the thread only run once ....
0
 
OBCTCommented:
Ohhhh nicley spotted :-p

Yes, threads are only meant to run the run() method once, then they go into the 'dead' state.
Seeing as your application doesn't really have a need for a thread, you can use everything in the run method, in your startApp() method.
Unless you have a process that you want to run in the background, theres no need for a thread.
You can remove the Runnable interface and the Thread instance. This will also improve the performance of your app because now there isn't any thread overhead.

Are there any other problems or questions?
0
 
tambunAuthor Commented:
It works !!!!!

Thanks ! here is the final code.

package jpgmidlet;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.Vector;
import java.io.IOException;
import java.io.DataInputStream;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.Connector;

public class JpgMidlet extends MIDlet implements Runnable
{
   private Display display;
   private Thread thread;
   private Frame frame;

   public JpgMidlet() {  
   }

   protected void startApp() {
      display = Display.getDisplay(this);
      frame = new Frame();

      Thread thread = new Thread(this);
      thread.start();
   }

   protected void pauseApp() {
   }

   protected void destroyApp(boolean unconditional) {
   }

   private Image createImage(String name) throws IOException {

       HttpConnection c = null;
       DataInputStream is = null;
           
       try {
          c = (HttpConnection)Connector.open(name);
          int status = c.getResponseCode();
       
          if (status != 200) {
             throw new IOException("HTTP Response Code = " + status);
          }

          int len = (int)c.getLength();
          String type = c.getType();

          if (len > 0) {
             is = c.openDataInputStream();
             byte[] data = new byte[len];
             is.readFully(data);
             return Image.createImage(data, 0, len);
          } else {
             throw new IOException("Content length is missing");
          }

       } finally {
          if (is != null)
             is.close();

          if (c != null)
             c.close();
       }

   }


   public void run() {
      Image theimage = null;

      String name = "http://127.0.0.1:11001/image.jpg";  
     
      while(true) {
        try {
           theimage = createImage(name);
        } catch (IOException e) {
          e.printStackTrace();
        }

        frame.setImages(theimage);
        display.setCurrent(frame);

      }
   }
}

class Frame extends Canvas {

    private Image image;
    private Thread tr;

    Frame() {
       image = Image.createImage(getWidth(), getHeight());    
    }

    void setImages(Image theimage) {
       image = theimage;  
       repaint();
       serviceRepaints();
    }

    protected void paint(Graphics g) {
       g.drawImage(image, 10, 50, Graphics.LEFT|Graphics.TOP);
    }

}
0
 
OBCTCommented:
Glad to have helped :-)
Good luck with your future J2ME apps!

Cheers

-OBCT
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.