图像的放大与缩小(1)——等距采样法
2016-07-14 18:14
701 查看
概述
图像的放大与缩小是图像处理中很经常碰到的问题,也是现实中经常要应用的,如一张图片太小,看不行的情况下就需要对去进行放大;在一些文档排版的时候有需要对一下大的图片进行缩小。图像的放大与缩小在物理意义上来说是图像的像素的尺寸放大或缩小相应的比例,但像素的尺寸是不能改变的,因此我们只能通过增加(或减少)相应的像素来放大(或缩小)图片。在算法实现中最简单的是等距离采样法。
算法的实现步骤:
(1)计算采样间隔
设原图的大小为W*H,将其放大(缩小)为(k1*W)*(K2*H),则采样区间为ii=1/k1; jj=1/k2;
当k1==k2时为等比例缩小;当k1!=k2时为不等比例放大(缩小);当k1<1
&& k2<1时为图片缩小,k1>1 && k2>1时图片放大。
(2)求出放大(缩小)后的图像
设原图为F(x,y)(i=1,2, ……W; j=1,2,……H),放大(缩小)的图像为G(x,y)(x=1,2, ……M;y=1,2,……N,其中M=W*k1,N=H*k2),则有
G(x,y) = f(ii*x, jj*y)
举例说明:
原图(6*4)f11 f12 f13 f14 f15 f16
f21 f22 f23 f24 f25 f26
f31 f32 f33 f34 f35 f36
f41 f42 f43 f44 f45 f46
缩小比例k1=0.6, k2 = 0.7
f12 f13 f15 f16
f32 f33 f35 f36
f42 f43 f45 f46
当然,使用等距采样法实现图片放大与缩小有一个缺点就是:缩小时未被选取的点的信息无法反映在缩小的图像上,放大时会出现整个小块区域像素相同,图像不清晰的,特别是缩放比例很大时。如下图
![](http://img.my.csdn.net/uploads/201210/13/1350108388_4462.jpg)
![](http://img.my.csdn.net/uploads/201210/13/1350108419_1909.jpg)
2048*1536缩小为100*80时的效果 100*80放大到600*400的效果
要解决这个问题,请看下一节“图像的放大与缩小(1)——双线性插值放大与均值缩小”
算法源代码(java)
[java] viewplain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
/**
* 读取图片
* @param srcPath 图片的存储位置
* @return 返回图片的BufferedImage对象
*/
public static BufferedImage readImg(String srcPath) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(srcPath));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
/**
* 将图片写入磁盘
* @param img 图像的BufferedImage对象
* @param s
* @param distPath 图像要保存的存储位置
*/
public static void writeImg(BufferedImage img, String s, String distPath) {
OutputStream out = null;
try {
//int imgType = img.getType();
//System.out.println("w:" + img.getWidth() + " h:" + img.getHeight());
out = new FileOutputStream(distPath);
ImageIO.write(img, s, out);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 等间隔采样的图像放大(缩小)
* @param img 要放大(缩小)的图像对象
* @param m 放大(缩小)后图像的宽
* @param n 放大(缩小)后图像的高
* @return 返回处理后的图像对象
*/
public static BufferedImage flex(BufferedImage img, int m, int n) {
float k1 = (float)m/img.getWidth();
float k2 = (float)n/img.getHeight();
return flex(img, k1, k2);
}
/**
* 等间隔采样的图像放大(缩小)
* @param img 要放大(缩小)的图像对象
* @param k1 要放大(缩小)的列比列
* @param k2 要放大(缩小)的行比列
* @return 返回处理后的图像对象
*/
public static BufferedImage flex(BufferedImage img, float k1, float k2) {
float ii = 1/k1; //采样的行间距
float jj = 1/k2; //采样的列间距
//int m=0 , n=0;
int imgType = img.getType();
int w = img.getWidth();
int h = img.getHeight();
int m = (int) (k1*w);
int n = (int) (k2*h);
int[] pix = new int[w*h];
pix = img.getRGB(0, 0, w, h, pix, 0, w);
System.out.println(w + " * " + h);
System.out.println(m + " * " + n);
int[] newpix = new int[m*n];
for(int j=0; j<n; j++) {
for(int i=0; i<m; i++) {
newpix[j*m + i] = pix[(int)(jj*j)*w + (int)(ii*i)];
}
}
System.out.println((int)((m-1)*ii));
System.out.println("m:" + m + " n:" + n);
BufferedImage imgOut = new BufferedImage( m, n, imgType);
imgOut.setRGB(0, 0, m, n, newpix, 0, m);
return imgOut;
}
相关文章推荐
- 整数数组的遍历
- swap分区
- android Window WindowManager 整理
- 连续区间最值问题
- node.js 下依赖Express 实现post 4种方式提交参数
- Eclipse之SVN插件离线安装(Mars.2 Release (4.5.2))
- 团体程序设计天梯赛-练习集L1-017. 到底有多二
- 团体程序设计天梯赛-练习集L1-016. 查验身份证
- 团体程序设计天梯赛-练习集L1-015. 跟奥巴马一起画方块
- 团体程序设计天梯赛-练习集L1-014. 简单题
- Python最好用的模板引擎Jinja
- 团体程序设计天梯赛-练习集L1-013. 计算阶乘和
- 团体程序设计天梯赛-练习集L1-012. 计算指数
- 团体程序设计天梯赛-练习集L1-011. A-B
- 最短路径
- 团体程序设计天梯赛-练习集L1-010. 比较大小
- Linux netstat命令详解
- 团体程序设计天梯赛-练习集L1-009. *N个数求和
- 团体程序设计天梯赛-练习集L1-008. 求整数段和
- 团体程序设计天梯赛-练习集L1-007. 念数字