J2ME经验总结之图片缩放 
fengzheng - BY - 2008-2-16 1:09:00

转载自:索尼爱立信开发者世界中文论坛 hunhun1981

public static Image ZoomImage(Image src, int desW, int desH) {
  Image desImg = null;
  int srcW = src.getWidth(); // 原始图像宽
  int srcH = src.getHeight(); // 原始图像高
  int[] srcBuf = new int[srcW * srcH]; // 原始图片像素信息缓存
  src.getRGB(srcBuf, 0, srcW, 0, 0, srcW, srcH);
  // 计算插值表
  int[] tabY = new int[desH];
  int[] tabX = new int[desW];
  int sb = 0;
  int db = 0;
  int tems = 0;
  int temd = 0;
  int distance = srcH > desH ? srcH : desH;
  for (int i = 0; i <= distance; i++) { /* 垂直方向 */
   tabY[db] = sb;
   tems += srcH;
   temd += desH;
   if (tems > distance) {
    tems -= distance;
    sb++;
   }
   if (temd > distance) {
    temd -= distance;
    db++;
   }
  }
  sb = 0;
  db = 0;
  tems = 0;
  temd = 0;
  distance = srcW > desW ? srcW : desW;
  for (int i = 0; i <= distance; i++) { /* 水平方向 */
   tabX[db] = (short) sb;
   tems += srcW;
   temd += desW;
   if (tems > distance) {
    tems -= distance;
    sb++;
   }
   if (temd > distance) {
    temd -= distance;
    db++;
   }
  }
  // 生成放大缩小后图形像素buf
  int[] desBuf = new int[desW * desH];
  int dx = 0;
  int dy = 0;
  int sy = 0;
  int oldy = -1;
  for (int i = 0; i < desH; i++) {
   if (oldy == tabY
) {
    System.arraycopy(desBuf, dy - desW, desBuf, dy, desW);
   } else {
    dx = 0;
    for (int j = 0; j < desW; j++) {
     desBuf[dy + dx] = srcBuf[sy + tabX[j]];
     dx++;
    }
    sy += (tabY
- oldy) * srcW;
   }
   oldy = tabY
;
   dy += desW;
  }
  // 生成图片
  desImg = Image.createRGBImage(desBuf, desW, desH, false);
  return desImg;
}

这个函数是我以前在网上搜罗到的,且不谈效果,性能什么的。只觉得它非常好用。
用了很长时间,可惜不知道是谁。真要谢谢这位作者了。
这个函数使用了midp2.0的getRGB()函数,效率不错,基本上没什么可优化的了。
此外,下面再提供一个midp1.0下可用的缩放函数,它是使用可变图片实现的。可惜这个函数也不是我写的。
转载于kobjects。不过性能确实比较差,毕竟要画那么多点嘛,跟处理图片数据的方法是没有可比性的。

 /* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the “Software”), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE. */

package org.kobjects.lcdui;
import javax.microedition.lcdui.*;
/** This class provides a single static method that allows to scale an image */

public class ScaleImage {
/**
* Creates a new, scaled version of the given image.
*
* @param src: The source image
* @param dstW: The destination (scaled) image width
* @param dstH: The destination (scaled) image height
* @return Image: A new Image object with the given width and height.
*/

public static Image scaleImage (Image src, int dstW, int dstH) {
int srcW = src.getWidth();
int srcH = src.getHeight();

Image tmp = Image.createImage(dstW, srcH);
Graphics g = tmp.getGraphics();

int delta = (srcW << 16) / dstW;
int pos = delta/2;
for (int x = 0; x < dstW; x++) {
g.setClip(x, 0, 1, srcH);
g.drawImage(src, x - (pos >> 16), 0, Graphics.LEFT | Graphics.TOP);
pos += delta;
}

Image dst = Image.createImage(dstW, dstH);
g = dst.getGraphics();

delta = (srcH << 16) / dstH;
pos = delta/2;

for (int y = 0; y < dstH; y++) {
g.setClip(0, y, dstW, 1);
g.drawImage(tmp, 0, y - (pos >> 16), Graphics.LEFT | Graphics.TOP);
pos += delta;
}
return dst;
}
}

它们的使用方法都是一目了然,提供原始图片对象以及目标宽度跟高度,它就生成新的图片,在成像效果上,感觉都差不多,我觉得第一个方法更好。在J2ME平台下,也没有必要去最求效果的极致,够用就好。再次感谢以上两个函数的作者。

  • 标签:J2ME 图片缩放 
  • Re:J2ME经验总结之图片缩放
    fengzheng - BY - 2008-2-18 9:14:00
    fengzheng谢谢!回去测试下!
    Re:J2ME经验总结之图片缩放
    zxw810809 - BY - 2008-2-18 6:53:00
    zxw810809我记得我改进过那个放缩算法,以前放到过论坛上,只需耗费更小的内存。
    下面再贴一遍
    private Image ZoomImage(Image srcImg, int desW, int desH) {
    int srcW = srcImg.getWidth(); //原始图像宽
    int srcH = srcImg.getHeight(); //原始图像高
    //计算插值表
    int[] tabY = new int[desH];
    int[] tabX = new int[desW];
    int sb = 0;
    int db = 0;
    int tems = 0;
    int temd = 0;
    int distance = srcH > desH ? srcH : desH;
    for (int i = 0; i <= distance; i++) { /*垂直方向*/
    tabY[db] = sb;
    tems += srcH;
    temd += desH;
    if (tems > distance) {
    tems -= distance;
    sb++;
    }
    if (temd > distance) {
    temd -= distance;
    db++;
    }
    }
    sb = 0;
    db = 0;
    tems = 0;
    temd = 0;
    distance = srcW > desW ? srcW : desW;
    for (int i = 0; i <= distance; i++) { /*水平方向*/
    tabX[db] = sb;
    tems += srcW;
    temd += desW;
    if (tems > distance) {
    tems -= distance;
    sb++;
    }
    if (temd > distance) {
    temd -= distance;
    db++;
    }
    }
    System.out.println((Runtime.getRuntime().freeMemory() / 1024));
    //生成放大缩小后图形像素buf
    Image desImg = Image.createImage(desW, desH);

    Graphics gs = desImg.getGraphics();
    int dx = 0;
    int oldy = -1;
    int[] srcBuf = new int[srcW];
    int[] desBuf = new int[desW];
    int[] lastRow = new int[desW];
    for (int i = 0; i < desH; i++) {
    if (oldy == tabY[i]) { //当上一行与即将要生成的这一行相同时,就直接copy了
    System.arraycopy(lastRow, 0, desBuf, 0, desW);
    } else { //插值算出新图片的一行
    srcImg.getRGB(srcBuf, 0, srcW, 0, dx, srcW, 1); //插值一行,就从原图中取一行数据
    for (int j = 0; j < desW; j++) {
    desBuf[j] = srcBuf[tabX[j]];
    }
    dx++;
    }
    System.arraycopy(desBuf, 0, lastRow, 0, desW);
    oldy = tabY[i];
    gs.drawRGB(desBuf, 0, desW, 0, i, desW, 1, false);

    }
    return desImg;
    }
    发表评论:

    Powered by Oblog.