知识大全 J2ME插值算法实现图片的放大缩小方法

Posted

篇首语:书籍是青年人不可分离的生活伴侣和导师。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 J2ME插值算法实现图片的放大缩小方法相关的知识,希望对你有一定的参考价值。

J2ME插值算法实现图片的放大缩小方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  前段时间接触了一些数字图像处理的问题 在 位师兄的指导下 在J ME平台 完成了一些基本的 D图像处理算法 就当是对这段知识做一下总结 决定把这些算法写出来 和各位朋友共同探讨 这篇文章先介绍图像放大缩小的实现 程序是以Nokia S 的机器为平台实现的

   实现图形缩放的基本思想

  图像的变形变换 简单的说就是把源图像每个点坐标通过变形运算转为目标图像相应点的新坐标 但是这样会导致一个问题就是目标点的坐标通常不会是整数 所以我们在做放大变换时 需要计算生成没有被映射到的点;而在缩小变换时 需要删除一些点 这里我们采用最简单的一种插值算法 最近邻域法 顾名思义 就是把非整数坐标作一个四舍五入 取最近的整数点

  看下面的一个图片放大的例子 左图为原始图像 右图为放大 倍的图像 里面的数字 表示所在像素的信息

  

  

   对于图片像素的操作

  获取Image图片像素信息

  标准的midp 没有提供获取图片像素信息的函数 对于NOKIA的机器 我们可以采用Nokia SDK提供的API获取像素信息 具体程序如下

     g = image getGraphics()   DirectGraphics dg = DirectUtils getDirectGraphics(g);   dg getPixels(short[] pixels  int offset  int scanlength  int x int y  int width  int height  int format)

  参数介绍

  short[] pixels 用于接收像素信息的数组

  int offset 这篇文章中的用到的地方 添 就可以了

  int scanlength 添图片的宽度就行了

  int x 添

  int y 添

  int width 图片宽度

  int height 图片高度

  int format 表示图形格式 好像Nokia S 的机器都是采用 格式表示RGB颜色的 就是红 绿 蓝各用 位表示 至于可以表示透明色ARGB的 格式 应该是机器硬件实现的

  想具体了解Nokia SDK的信息 可以查看Nokia SDK的帮助文档

  使用像素信息数组生成Image图片

     image = Image createImage(w  h);   g = image getGraphics()   DirectGraphics dg = DirectUtils getDirectGraphics(g);   dg drawPixels(short[] pixels boolean transparency  int offset  int scanlength  int x  int y  int width int height  int manipulation  int format)   short[] pixels 像素信息数组   boolean transparency 是否包含alpha位信息   int offset 添    int scanlength 添图片的宽度就行了   int x 添    int y 添    int width 图片宽度   int height 图片高度   int manipulation 添    int format

  下面开始介绍具体的算法 首先给出图像缩放的完整函数 然后对代码 分段进行解释

  /*********************************

  * @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(); //原始图像高   short[] srcBuf = new short[srcW * srcH]; //原始图片像素信息缓存   //srcBuf获取图片像素信息   Image desImg = Image createImage(srcW  srcH);   if (srcImg isMutable())  /*如果是可变图像*/   DirectUtils getDirectGraphics(srcImg getGraphics())   getPixels(srcBuf    srcW      srcW  srcH   );    else  /*如果是非可变图像*/   desImg getGraphics() drawImage(srcImg       );   DirectUtils getDirectGraphics(desImg getGraphics())   getPixels(srcBuf    srcW      srcW  srcH   );      //计算插值表   short[] tabY = new short[desH];   short[] tabX = new short[desW];   int sb =  ;   int db =  ;   int tems =  ;   int temd =  ;   int distance = srcH > desH ? srcH : desH;   for (int i =  ; i <= distance; i++)  /*垂直方向*/   tabY[db] = (short) sb;   tems += srcH;   temd += desH;   if (tems > distance)    tems  = distance;   sb++;      if (temd > distance)    temd  = distance;   db++;         sb =  ;   db =  ;   tems =  ;   temd =  ;   distance = srcW > desW ? srcW : desW;   for (int i =  ; i <= distance; i++)  /*水平方向*/   tabX[db] = (short) sb;   tems += srcW;   temd += desW;   if (tems > distance)    tems  = distance;   sb++;      if (temd > distance)    temd  = distance;   db++;      

//生成放大缩小后图形像素buf   short[] desBuf = new short[desW * desH];   int dx =  ;   int dy =  ;   int sx =  ;   int sy =  ;   int oldy =  ;   for (int i =  ; i < desH; i++)    if (oldy == tabY[i])    System arraycopy(desBuf  dy   desW  desBuf  dy  desW);    else    dx =  ;   for (int j =  ; j < desW; j++)    desBuf[dy + dx] = srcBuf[sy + tabX[j]];   dx++;      sy += (tabY[i]   oldy) * srcW;      oldy = tabY[i];   dy += desW;      //生成图片   desImg = Image createImage(desW  desH);   DirectUtils getDirectGraphics(desImg getGraphics())   drawPixels(desBuf  true    desW      desW  desH     );   return desImg;   

  首先看函数的头两句 很容易 就是获取原始图片的宽度和高度

     int srcW = srcImg getWidth(); //原始图像宽   int srcH = srcImg getHeight(); //原始图像高

  接下来一句我们要定义一个short型数组 作为获取原始图片像素信息的缓存

    short[] srcBuf = new short[srcW * srcH];

  再下来一段 有的朋友可能会有些不明白 这里要解释一下 由于getPixels()这个函数 只能获取可变图像的像素信息 非可变图像 无法获取像素信息 所以我们要用srcImg isMutable() 来判断 原始图像是不是可变图像 然后分两种情况来处理 如果srcImg是可变图像 我们就直接用getPixels()来获取它的像素信息 并保存在srcBuf里 如果srcImg不是可变图像 我们就需要把srcImage画到事先生成的可变图像desImg上 然后再获取desImg的像素信息

  

    Image desImg = Image createImage(srcW  srcH);   if (srcImg isMutable())  /*如果是可变图像*/   DirectUtils getDirectGraphics(srcImg getGraphics())   getPixels(srcBuf    srcW      srcW  srcH   );    else  /*如果是非可变图像*/   desImg getGraphics() drawImage(srcImg       );   DirectUtils getDirectGraphics(desImg getGraphics())   getPixels(srcBuf    srcW      srcW  srcH   );   

  再往下就是缩放算法的重点 插值表的生成 插值表分水平差值表和垂直插值表 我们要分别生成原始图像矩阵的 种插值表 然后利用插值表生成放大缩小后的图像矩阵 由于这个内容比较抽象 很难用文字表述清楚 所以我们用实例进行介绍

  大家看下面这个水平的 * 的表格

  

  | | | | |

  

  如果要将这个表格放大成 * 的表格 放大的表格比原始表格多出了 个格子 我们只能对这多出来的 个格子进行插值 才能完成放大的操作 现在结合生成水平插值表的代码来完成这个过程

    distance = srcW > desW ? srcW : desW;   for (int i =  ; i <= distance; i++)  /*水平方向*/   tabX[db] = (short) sb;   tems += srcW;   temd += desW;   if (tems > distance)    tems  = distance;   sb++;      if (temd > distance)    temd  = distance;   db++;      

  很明显原始表格宽度srcW = ;放大后的表格宽度desW = ;所以distance = desW =

  接下来进入for循环 我们一步步的演算其循环的过程

  

  | i| tabX赋值操作| tems | temd| sb | db |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  | | tabX[ ] = | | | | |

  

  有此得到放大后 * 的表格为下图所示 其中每一个单元格中的数字n表示这个单元格的内容 和原始表格中第n个单元格的内容一样

  

  | | | | | | |

  

  例如 左图为原始表格 右图为放大的表格

  

  | 红 | 绿 | 兰 | 紫 | | 红 | 绿 | 绿 | 兰 | 紫 | 紫 |

  

  同样 垂直方向的插值表我们也可以用相同的方法获得

  有了 个插值表 下面就可以生成放大和缩小后的图像了

     short[] desBuf = new short[desW * desH];   int dx =  ;   int dy =  ;   int sx =  ;   int sy =  ;   int oldy =  ;   for (int i =  ; i < desH; i++)    if (oldy == tabY[i])  /**********情况一**********/   System arraycopy(desBuf  dy   desW  desBuf  dy  desW);    else  /**********情况二**********/   dx =  ;   for (int j =  ; j < desW; j++)    desBuf[dy + dx] = srcBuf[sy + tabX[j]];   dx++;      sy += (tabY[i]   oldy) * srcW;      oldy = tabY[i];   dy += desW;   

  desBuf是用来保存放大缩小后的图像数据 例如我们把一个 * 像素的图像A放大成 * 的图像B 据前面的介绍我们可以生成 个插值表 tabX = tabY =

  在循环中会判断是否oldy 等于 tabY[i] 这个操作等同于tabY[i ]是否等于tabY[i] 如果等于 表示图像B前一行已经生成的数据和即将要生成的第i行数据相同 则只要执行System arraycopy(desBuf dy desW desBuf dy desW)把上一行的数据复制过来即可;如果不等 则需要对照水平插值表tabX生成这一行的数据

  算法演示过程如下

  

  | i|oldy|tabY[i]|运算情况|

  

  | | | | 情况 |

  

  | | | | 情况 |

  

  | | | | 情况 |

  

  | | | | 情况 |

  

  | | | | 情况 |

  

  | | | | 情况 |

  

  然后我们用desBuf生成最终放大或缩小后的图片

     desImg = Image createImage(desW  desH);   DirectUtils getDirectGraphics(desImg getGraphics())   drawPixels(desBuf  true    desW      desW  desH     );   return desImg;

cha138/Article/program/Java/hx/201311/26482

相关参考

知识大全 pa怎么缩小图片容量,以及将图片改成500*500的大小

pa怎么缩小图片容量,以及将图片改成500*500的大小图像---图像大小,然后自己输入数值,最后,点文件---存储为Web所用格式,选择jpg格式,选择高或中质量,保存。怎样缩小图片容量大小?用PS

知识大全 js实现缩小网页内所有图片大小

  javascript遍历网页内的所有图片根据图片的宽高按一定的比率缩小javascript 缩小网页内所有图片大小的方法函数如下:  */<scriptlanguage="java

知识大全 怎么缩小图片尺寸

怎么缩小图片尺寸用系统自带的画图工具可以实现,把图片复制,贴上到画图板上,然后点“图象”再点“拉升/扭曲”,在拉升的下面水平和垂直后面的框里填上百分比,如需要缩小成20%,你就填上20就行了,后面就是

知识大全 JS等比例缩小图片尺寸

JS等比例缩小图片尺寸  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为了提升用户体验网站用户在

知识大全 jQuery当鼠标悬停时放大图片的效果实例

jQuery当鼠标悬停时放大图片的效果实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这个效

知识大全 jquery图片不完全按比例自动缩小的简单代码

开发前期用自动生产固定大小的图片进行显示发现不能满足在前期的时候把保存了原图现在只能显示原图原图由于上传时候没有做任何限制所有要使用图片不完全按比例缩小下面是代码 复制代码代码如下:lish

知识大全 用ps怎么放大图片里的人物大小,其他不变

用ps怎么放大图片里的人物大小,其他不变是一个图层吗?是一个的话你得先把人物扣出来再用自由变换工具调节使其变大。先用钢笔工具把人物扣出来之后CTRL+T选中人物按住SHIFT键拉四个角中的任何一个角就

知识大全 J2ME 带给移动支付的优势解析

J2ME带给移动支付的优势解析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  移动支付是一种在移

知识大全 通过实例论证J2ME的事件传输机制

通过实例论证J2ME的事件传输机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文主要阐述的

知识大全 J2ME数组的复制及连接操作方法

J2ME数组的复制及连接操作方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  pub