WEB开发网
开发学院软件开发Java 基于MIDP2.0实现图片的缩放功能 阅读

基于MIDP2.0实现图片的缩放功能

 2007-12-23 12:34:34 来源:WEB开发网   
核心提示: 以前在SUN的论坛看到过关于图片缩放的处理,是基于MIDP2.0实现的,基于MIDP2.0实现图片的缩放功能,今天看到有网友在问这个问题,因此去翻了一下以前的帖子找到了源代码,我准备了一个图片,然后写了一个测试的MIDlet,自己写了一个测试程序验证了一下效果还算可以,希望可以解这位网友的燃眉之急

   以前在SUN的论坛看到过关于图片缩放的处理,是基于MIDP2.0实现的。今天看到有网友在问这个问题,因此去翻了一下以前的帖子找到了源代码,自己写了一个测试程序验证了一下效果还算可以。希望可以解这位网友的燃眉之急。

   源代码如下:

package com.j2medev.image;

import javax.microedition.lcdui.*;


public class ImageUtil
{


   // fixed point constants
   PRivate static final int FP_SHIFT = 13;

   private static final int FP_ONE = 1 << FP_SHIFT;

   private static final int FP_HALF = 1 << (FP_SHIFT - 1);

   // resampling modes - valid values for the mode parameter of resizeImage()
   // any other value will default to MODE_BOX_FILTER because of the way the
   // conditionals are set in resizeImage()
   public static final int MODE_POINT_SAMPLE = 0;

   public static final int MODE_BOX_FILTER = 1;

   /**
   * getPixels Wrapper for pixel grabbing techniques. I separated this step
   * into it's own function so that other APIs (Nokia, Motorola, Siemens,
   * etc.) can easily substitute the MIDP 2.0 API (Image.getRGB()).
   *
   * @param src
   *       The source image whose pixels we are grabbing.
   * @return An int array containing the pixels in 32 bit ARGB format.
   */
   int[] getPixels(Image src)
   {
     int w = src.getWidth();
     int h = src.getHeight();
     int[] pixels = new int[w * h];
     src.getRGB(pixels, 0, w, 0, 0, w, h);
     return pixels;
   }

   /**
   * drawPixels Wrapper for pixel drawing function. I separated this step into
   * it's own function so that other APIs (Nokia, Motorola, Siemens, etc.) can
   * easily substitute the MIDP 2.0 API (Image.createRGBImage()).
   *
   * @param pixels
   *       int array containing the pixels in 32 bit ARGB format.
   * @param w
   *       The width of the image to be created.
   * @param h
   *       The height of the image to be created. This parameter is
   *       actually superfluous, because it must equal pixels.length / w.
   * @return The image created from the pixel array.
   */
   Image drawPixels(int[] pixels, int w, int h)
   {
     return Image.createRGBImage(pixels, w, h, true);
   }


   /**
   * resizeImage Gets a source image along with new size for it and resizes
   * it.
   *
   * @param src
   *       The source image.
   * @param destW
   *       The new width for the destination image.
   * @param destH
   *       The new heigth for the destination image.
   * @param mode
   *       A flag indicating what type of resizing we want to do. It
   *       currently supports two type: MODE_POINT_SAMPLE - point sampled
   *       resizing, and MODE_BOX_FILTER - box filtered resizing
   *       (default).
   * @return The resized image.
   */
   Image resizeImage(Image src, int destW, int destH, int mode)
   {
     int srcW = src.getWidth();
     int srcH = src.getHeight();

   // create pixel arrays
     int[] destPixels = new int[destW * destH]; // array to hold destination
                          // pixels
     int[] srcPixels = getPixels(src); // array with source's pixels

   if (mode == MODE_POINT_SAMPLE)
     {
       // simple point smapled resizing
       // loop through the destination pixels, find the matching pixel on
       // the source and use that
       for (int destY = 0; destY < destH; ++destY)
       {
         for (int destX = 0; destX < destW; ++destX)
         {
           int srcX = (destX * srcW) / destW;
           int srcY = (destY * srcH) / destH;
           destPixels[destX + destY * destW] = srcPixels[srcX + srcY
               * srcW];
         }
       }
     } else
     {
       // precalculate src/dest ratios
       int ratioW = (srcW << FP_SHIFT) / destW;
       int ratioH = (srcH << FP_SHIFT) / destH;


       int[] tmpPixels = new int[destW * srcH]; // temporary buffer for the
                           // horizontal resampling
                           // step

     // variables to perform additive blending
       int argb; // color extracted from source
       int a, r, g, b; // separate channels of the color
       int count; // number of pixels sampled for calculating the average

     // the resampling will be separated into 2 steps for simplicity
       // the first step will keep the same height and just stretch the
       // picture horizontally
       // the second step will take the intermediate result and stretch it
       // vertically

     // horizontal resampling
       for (int y = 0; y < srcH; ++y)
       {
         for (int destX = 0; destX < destW; ++destX)
         {
           count = 0;
           a = 0;
           r = 0;
           b = 0;
           g = 0; // initialize color blending vars
           int srcX = (destX * ratioW) >> FP_SHIFT; // calculate
                               // beginning of
                               // sample
           int srcX2 = ((destX + 1) * ratioW) >> FP_SHIFT; // calculate
                                   // end of
                                   // sample


           // now loop from srcX to srcX2 and add up the values for
           // each channel
           do
           {
             argb = srcPixels[srcX + y * srcW];
             a += ((argb & 0xff000000) >> 24); // alpha channel
             r += ((argb & 0x00ff0000) >> 16); // red channel
             g += ((argb & 0x0000ff00) >> 8); // green channel
             b += (argb & 0x000000ff); // blue channel
             ++count; // count the pixel
             ++srcX; // move on to the next pixel
           } while (srcX <= srcX2
               && srcX + y * srcW < srcPixels.length);

         // average out the channel values
           a /= count;
           r /= count;
           g /= count;
           b /= count;

         // recreate color from the averaged channels and place it
           // into the temporary buffer
           tmpPixels[destX + y * destW] = ((a << 24) (r << 16)
               (g << 8) b);
         }
       }


       // vertical resampling of the temporary buffer (which has been
       // horizontally resampled)
       System.out.println("Vertical resampling...");
       for (int x = 0; x < destW; ++x)
       {
         for (int destY = 0; destY < destH; ++destY)
         {
           count = 0;
           a = 0;
           r = 0;
           b = 0;
           g = 0; // initialize color blending vars
           int srcY = (destY * ratioH) >> FP_SHIFT; // calculate
                               // beginning of
                               // sample
           int srcY2 = ((destY + 1) * ratioH) >> FP_SHIFT; // calculate
                                   // end of
                                   // sample


           // now loop from srcY to srcY2 and add up the values for
           // each channel
           do
           {
             argb = tmpPixels[x + srcY * destW];
             a += ((argb & 0xff000000) >> 24); // alpha channel
             r += ((argb & 0x00ff0000) >> 16); // red channel
             g += ((argb & 0x0000ff00) >> 8); // green channel
             b += (argb & 0x000000ff); // blue channel
             ++count; // count the pixel
             ++srcY; // move on to the next pixel
           } while (srcY <= srcY2
               && x + srcY * destW < tmpPixels.length);

         // average out the channel values
           a /= count;
           a = (a > 255) ? 255 : a;
           r /= count;
           r = (r > 255) ? 255 : r;
           g /= count;
           g = (g > 255) ? 255 : g;
           b /= count;
           b = (b > 255) ? 255 : b;


           // recreate color from the averaged channels and place it
           // into the destination buffer
           destPixels[x + destY * destW] = ((a << 24) (r << 16)
               (g << 8) b);
         }
       }
     }

   // return a new image created from the destination pixel buffer
     return drawPixels(destPixels, destW, destH);
   }

}

   有兴趣的网友可以仔细研究一下。我准备了一个图片,然后写了一个测试的MIDlet。下面是效果对比。


基于MIDP2.0实现图片的缩放功能(图一)

基于MIDP2.0实现图片的缩放功能(图二)

/*
 * Created on 2004-12-24
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.j2medev.image;

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


public class TestMIDlet extends MIDlet
{
   private Display display;

   private Form form;

   protected void startApp() throws MIDletStateChangeException
   {
    
     display = Display.getDisplay(this);
     Image srcImage = null;
     try
     {
       srcImage = Image.createImage("/welcome.png");

   } catch (IOException e)
     {
     }
     ImageUtil iu = new ImageUtil();
     form = new Form("Image");
     int width = form.getWidth();
     int height = form.getHeight();
     Image destImage = iu.resizeImage(srcImage, width, height,
         ImageUtil.MODE_POINT_SAMPLE);
     form.append(destImage);
     display.setCurrent(form);


   }


   protected void pauseApp()
   {
   
   }


   protected void destroyApp(boolean arg0) throws MIDletStateChangeException
   {
    

   }

}

(出处:http://www.cncms.com)


Tags:基于 MIDP 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接