.png image bug

I’m using Image.getRGB and Image.createRGBImage to resize images in midp2.0. It works fine on the emulator. But when I run the game on my palm tungsten E, with the ibm j9 kvm, I get a wierd error. When the image is painted it shows a red square the size of the image. I found that if I turn double-buffering off it paints the image correctly. Also I found that the image is painted correctly with double buffering on, when I save the original image as a 24 bit rgb image. When I save the image as a 8bit indexed color image, it works on the emulator, but not on the device. Any ideas if this is a problem on other devices or how I can save the image as 8bit and still get it to display properly?

Have you tested on Nokia series 60 at all? There is a major bug with regards to image creation with the createRGBImage() method in that you should be unable to an image of size larger than 4095 ints (tha array that contains the image data). Please let me know if you have not experienced this problem.

Cheers,

ribot

I haven’t been able to test on any nokia series 60 devices. I have tried it with a series 60 emulator but I get the error “no such method getRGB” I guessing the series 60 emulator I have is not midp 2.0. Encase your wondering I have found a work around for the 4095 int limit. The code is below, basically I resize strips of the image that are less than 4095 int big, then put them back together in one image. It’s takes more runtime memory, but doesnt use more than 4095 ints at one time.


try {
 boardImg=Image.createImage ("/images/board.png");
 
 Image pieceImage,newImage;
 newImage=Image.createImage(boardWidth,boardHeight);
 Graphics newImageG=newImage.getGraphics();
 //board width =180, board height = 160
 int rgbdata[] = new int [180*(160/10)];
 for (p=0;p<10;p++) {
 boardImg.getRGB (rgbdata,0,180,0,p*(16),180,16);
 pieceImage=Image.createRGBImage (rgbdata,180,16,false);
 pieceImage=resize (pieceImage,boardWidth,(boardHeight/10));
 newImageG.drawImage (pieceImage,0,p*(boardHeight/10),0);
 pieceImage=null;
 System.gc();
 }
 boardImg=newImage;
 newImage=null;

 System.gc();
//boardImg=resize (boardImg,boardWidth,boardHeight);
 
      } catch (Exception e) {System.out.println ("Error loading images: "+e);}
 }

The more strips you create the more likely the image will be off somewhat. If your interested in my resize code, I found it in the forums from a member named Yu You, I had written a similar resize code before but Yu You’s was much faster than mine. It is below.


        public static Image resize(Image originalImage, int width, int height) { 
              //if (height <= 0 || width <= 0) 
              //throw new Exception("ERROR_INVALID_ARGUMENT"); 
              if (originalImage == null) 
                    return Image.createImage(height, width); 
              int orig_h = originalImage.getHeight(); 
              int orig_w = originalImage.getWidth(); 
              if (orig_w == width && orig_h == height) 
                    return originalImage; 
              int[] orig = new int[orig_h * orig_w]; 
              originalImage.getRGB(orig, 0, orig_w, 0, 0, orig_w, orig_h); 
              int index; 
              int[] newbuffer = new int[height * width]; 
              int loc, oldloc = 0; 
              //long before = System.currentTimeMillis(); 
              for (int i = 0; i < height; i++) { 
                    for (int j = 0; j < width; j++) { 
                          loc = i * width + j; 
                          index = (int) (i * orig_h / height) * orig_w 
                                      + (int) (j * orig_w / width); 
                          //System.arraycopy(orig,index,newbuffer,loc,1); 
                          newbuffer[loc] = orig[index]; 
                    } 
              } 
              //System.out.println("time:"+(System.currentTimeMillis()-before)); 
             Image newImage = Image.createRGBImage(newbuffer, width, height, false); 
              orig = null; 
              newbuffer = null; 
              System.gc(); //  
              return newImage; 
        } 

The solution I’ve finnally come up with is to not use getRgb and createRGBIMage at all. Since I’m not worried about tranparent pixels in this game, I instead set a clip region in the image im resizing and paint the old image. Its very slow is the only probelm. I modified Yu You’s code to use image painting instead of getRGB and now it works on my device and is midp 1.0 compatible. Only problem is its slow and it doesnt work for transparent images because of the createImage (width,height); The code is listed below:


public static Image resize2(Image originalImage, int width, int height) { 
                          //if (height <= 0 || width <= 0) 
                          //throw new Exception("ERROR_INVALID_ARGUMENT"); 
                          if (originalImage == null) 
                                return Image.createImage(height, width); 
                          int orig_h = originalImage.getHeight(); 
                          int orig_w = originalImage.getWidth(); 
                          if (orig_w == width && orig_h == height) 
                                return originalImage; 
                          int index; 
                          int loc, oldloc = 0; 
                          Image newImage = Image.createImage (width,height);
                          Graphics newImageG=newImage.getGraphics();
                          //long before = System.currentTimeMillis(); 
                          for (int i = 0; i < height; i++) { 
                                for (int j = 0; j < width; j++) { 
                                      //System.arraycopy(orig,index,newbuffer,loc,1); 
                                    //  newbuffer[loc] = orig[index]; 
                                      newImageG.setClip (j,i,1,1);
                                      newImageG.drawImage (originalImage,j-(int) (j*orig_w/width),i-(int) (i*orig_h/height),0);
                                } 
                          } 
                          //System.out.println("time:"+(System.currentTimeMillis()-before)); 
                         //Image newImage = Image.createRGBImage(newbuffer, width, height, false); 
                         // orig = null; 
                         // newbuffer = null; 
                         originalImage=null;      
                         System.gc(); //  
                          return newImage; 
                    }