转自: baby6 – ( http://baby66.bokee.com/6557235.html )
昨天在网上找了一段j2me下的图片插值算法,不过这段算法需要nokiaui的支持,但是并不是所有手机都支持nokiaui的扩展包,而且这个算法巨费内存。
我把它修改了一下,改为对某行插值的时候才把原图的对应的那行数据取出来,然后再把这行画在一张图片上,这样避免了构造两个很大的int数组,从而可以省很多内存,
/************************************************************
* @todo 图片放大缩小
* @param srcImg 原始图片
* @param desW 变化后图片的宽
* @param desH 变化后图片的高
* @return 处理后的图片
************************************************************/
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;
}