图像的放大与缩小,以及旋转(Java实现)

对于图像的处理,其实就是对矩阵的处理,所以我们可以将图像的放大与缩小以及旋转问题转换为矩阵的放缩以及旋转。

对于图像的放缩,采用了线性插值:
https://blog.csdn.net/xiaqunfeng123/article/details/17362881

原理(步骤):

  1. 通过原始图像和比例因子得到新图像的大小,并创建图像
  2. 对(x1,y1)取整得到(xx,yy),(xx+1,yy),(xx,yy+1),(xx+1,yy+1)
  3. 利用双线性插值得到像素点(x,y)的值,并写回新图像
  4. 重复上面步骤,直到新图像的所有像素写完

直接上代码

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(y1-yy1))*color1.getGreen()
                            +(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy2))*color2.getGreen();
                    b=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getBlue()
                            +(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy2))*color2.getBlue();
                    gs.setColor(new Color((int)Math.min(255,Math.abs(r)),(int)Math.min(255,Math.abs(g)),(int)Math.min(255,Math.abs(b))));
                    gs.fillRect(i,j,1,1);
                }else if(xx1!=tempImage.getWidth()-1&&yy1==tempImage.getHeight()-1){
                    Color color1=new Color(tempImage.getRGB((int)xx1,(int)yy1));
                    Color color3=new Color(tempImage.getRGB((int)xx2,(int)yy1));
                    r=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getRed()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getRed();
                    g=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getGreen()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getGreen();
                    b=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getBlue()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getBlue();
                    gs.setColor(new Color((int)Math.min(255,Math.abs(r)),(int)Math.min(255,Math.abs(g)),(int)Math.min(255,Math.abs(b))));
                    gs.fillRect(i,j,1,1);
                }else if(xx1==tempImage.getWidth()-1&&yy1==tempImage.getHeight()-1){
                    Color color1=new Color(tempImage.getRGB((int)xx1,(int)yy1));
                    r=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getRed();
                    g=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getGreen();
                    b=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getBlue();
                    gs.setColor(new Color((int)Math.min(255,Math.abs(r)),(int)Math.min(255,Math.abs(g)),(int)Math.min(255,Math.abs(b))));
                    gs.fillRect(i,j,1,1);
                }else{
                    //获取四个位置的Color对象
                    Color color1=new Color(tempImage.getRGB((int)xx1,(int)yy1));
                    Color color2=new Color(tempImage.getRGB((int)xx1,(int)yy2));
                    Color color3=new Color(tempImage.getRGB((int)xx2,(int)yy1));
                    Color color4=new Color(tempImage.getRGB((int)xx2,(int)yy2));
                    //对r,g,b进行权值计算
                    r=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getRed()
                            +(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy2))*color2.getRed()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getRed()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy2))*color4.getRed();

                    g=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getGreen()
                            +(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy2))*color2.getGreen()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getGreen()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy2))*color4.getGreen();

                    b=(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy1))*color1.getBlue()
                            +(1-Math.abs(x1-xx1))*(1-Math.abs(y1-yy2))*color2.getBlue()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy1))*color3.getBlue()
                            +(1-Math.abs(x1-xx2))*(1-Math.abs(y1-yy2))*color4.getBlue();
//                    System.out.println("r=  "+(int)Math.min(255,r)+"  g=  "+(int)Math.min(255,g)+"  b=  "+(int)Math.min(255,b));
                    gs.setColor(new Color((int)Math.min(255,Math.abs(r)),(int)Math.min(255,Math.abs(g)),(int)Math.min(255,Math.abs(b))));
                    gs.fillRect(i,j,1,1);
                }
            }
        }
        return newImage;
    }

.
图像的旋转
规律: 顺时针旋转90度:原像素点的纵坐标变为新像素的横坐标,原像素的横坐标与矩阵宽的差值绝对值是新像素的纵坐标
逆时针旋转90度:原像素点的横坐标变为新像素的纵坐标,原像素的纵坐标与矩阵的高的差值的绝对值是新像素的横坐标

//顺时针
public Image change(Image image){
        BufferedImage tempImage=(BufferedImage) image;
        BufferedImage newImage=new BufferedImage(tempImage.getHeight(),tempImage.getWidth(),BufferedImage.TYPE_INT_RGB);
        int index=tempImage.getHeight()-1;
        for(int i=0;i<tempImage.getHeight();i++,index--){
            for(int j=0;j<tempImage.getWidth();j++){
                newImage.setRGB(index,j,tempImage.getRGB(j,i));
            }
        }
        return newImage;
    }
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值