对于图像的处理,其实就是对矩阵的处理,所以我们可以将图像的放大与缩小以及旋转问题转换为矩阵的放缩以及旋转。
对于图像的放缩,采用了线性插值:
https://blog.csdn.net/xiaqunfeng123/article/details/17362881
原理(步骤):
- 通过原始图像和比例因子得到新图像的大小,并创建图像
- 对(x1,y1)取整得到(xx,yy),(xx+1,yy),(xx,yy+1),(xx+1,yy+1)
- 利用双线性插值得到像素点(x,y)的值,并写回新图像
- 重复上面步骤,直到新图像的所有像素写完
直接上代码
public Image changeImg(Image img,double xScale,double yScale){
//通过原始图像和比例因子得到新图像的大小,并创建图像
//对(x1,y1)取整得到(xx,yy),(xx+1,yy),(xx,yy+1),(xx+1,yy+1)
//利用双线性插值得到像素点(x,y)的值,并写回新图像
//重复上面步骤,直到新图像的所有像素写完
BufferedImage tempImage=(BufferedImage)img;
BufferedImage newImage=new BufferedImage((int)(tempImage.getWidth()*xScale),(int)(tempImage.getHeight()*yScale),BufferedImage.TYPE_INT_RGB);
Graphics gs=newImage.getGraphics();
//由新图像的某个像素(x,y)映射到原始图像(x1,y1)处
for(int i=0;i<newImage.getWidth();i++){
for(int j=0;j<newImage.getHeight();j++){
double r,g,b;
//新图映射到原图的x坐标
double x1=i*(1/xScale);
//新图映射到原图的y坐标
double y1=j*(1/yScale);
//f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
//取整
double xx1=(double)Math.round(x1);
double yy1=(double)Math.round(y1);
double xx2=xx1+1;
double yy2=yy1+1;
//
if(xx1==tempImage.getWidth()-1&&yy1!=tempImage.getHeight()-1){
Color color1=new Color(tempImage.getRGB((int)xx1,(int)yy1));
Color color2=new Color(tempImage.getRGB((int)xx1,(int)yy2));
r=(1d-Math.abs(x1-xx1))*(1d-Math.abs(y1-yy1))*color1.getRed()
+(1d-Math.abs(x1-xx1))*(1d-Math.abs(y1-yy2))*color2.getRed();
g=(1-Math.abs(x1-xx1))*(1-Math.abs