-
图像双线性插值放大
f(x,y)=f(0,0)(1-x)(1-y)+f(1,0)x(1-y)+f(0,1)(1-x)y+f(1,1)xy
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 图像双线性插值放大
* f(x,y)=f(0,0)(1-x)(1-y)+f(1,0)x(1-y)+f(0,1)(1-x)y+f(1,1)xy
* */
public class ch5_2 {
public static void main(String[] args) throws Exception {
long t1=System.currentTimeMillis(); //获取程序运行前的时间,单位毫秒
BufferedImage bi=ImageIO.read(new File("1.jpg")); //读取图像
BufferedImage nbi=zoomSxx(bi,4); //处理图像
ImageIO.write(nbi, "jpg", new File("1b.jpg")); //输出图像
long t2=System.currentTimeMillis(); //获取程序运行后的时间
System.out.println("程序运行"+(t2-t1)+"毫秒"); //程序结束后进行提示
}
/**
* 图像双线性插值放大
* @param BufferedImage bi 原始图像
* @param double k 放大系数
* @return BufferedImage 变换后图像
* */
public static BufferedImage zoomSxx(BufferedImage bi, double k) {
int w=(int) (k*bi.getWidth()); //得到图像的宽度
int h=(int) (k*bi.getHeight()); //得到图像的高度
BufferedImage nbi=new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
//创建新图像(临时图像变量)宽度和高度跟原图相同
//循环遍历每一个像素点
for(int y1=0;y1<h;y1++) {
for(int x1=0;x1<w;x1++) {
//计算输出图像坐标(x1,y1)所对应原图中的插值像素值
int rgb=zoomSxx(bi,k,x1,y1);
nbi.setRGB(x1, y1, rgb); //设置输出图像坐标为(x,y)的像素值
}
}
return nbi;
}
private static int zoomSxx(BufferedImage bi, double k, int x1, int y1) {
double xx=x1/k;
double yy=y1/k;
int x0=(int) xx;
int y0=(int) yy;
int rgb=0;
if((x0+1)<bi.getWidth() && (y0+1)<bi.getHeight()){
Color a=new Color(bi.getRGB(x0, y0));
Color b=new Color(bi.getRGB(x0+1, y0));
Color c=new Color(bi.getRGB(x0, y0+1));
Color d=new Color(bi.getRGB(x0+1, y0+1));
int r0=zoomSxx(a.getRed(),b.getRed(),c.getRed(),d.getRed(),xx-x0,yy-y0);
int g0=zoomSxx(a.getGreen(),b.getGreen(),c.getGreen(),d.getGreen(),xx-x0,yy-y0);
int b0=zoomSxx(a.getBlue(),b.getBlue(),c.getBlue(),d.getBlue(),xx-x0,yy-y0);
Color nc=new Color(r0,g0,b0);
rgb=nc.getRGB();
}
return rgb;
}
private static int zoomSxx(int a, int b,int c, int d,double xx,double yy) {
double y=a*(1-xx)*(1-yy)+b*xx*(1-yy)+c*(1-xx)*yy+d*xx*yy;
return (int)y;
}
}