java缩放图片、java裁剪图片代码工具类

2018-06-19 16:39:03
  • 一首先看下效果

  • 二工具类

  • 三测试类

在系统的上传图片功能中,我们无法控制用户上传图片的大小,用户可能会上传大到几十M小到1k的的图片,一方面图片太大占据了太多的空间,另一方面,我们没办法在页面上显示统一大小的图片。所以我们需要对用户上传的图片进行缩放和裁剪,这里的缩放和平常的压缩不是一个意思,因为要实现小的图片会放大,大的图片会缩小,而且是等比例变的,图片不会显示挤压的效果。而这种操作Java完全可以实现。下面分享下java缩放、裁剪图片的工具类。

一、首先看下效果:

1.jpg为原图,yasuo.jpg是缩放后的,caijian.jpg是在yasuo.jpg基础上裁掉两边各10像素得到的 
这里写图片描述 
这里写图片描述 
比较1.jpg,是不是既图片小了,又得到了想要的图片大小,而且图片没有被挤压? 下面来看代码:

二、工具类:

复制代码

import java.awt.Color;import java.awt.Graphics2D;import java.awt.Image;import java.awt.geom.AffineTransform;import java.awt.image.AffineTransformOp;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;/**
 * 裁剪、缩放图片工具类
 * @author CSDN 没有梦想-何必远方 
 */public class ImgUtils {    /**
     * 缩放图片方法
     * @param srcImageFile 要缩放的图片路径
     * @param result 缩放后的图片路径
     * @param height 目标高度像素
     * @param width  目标宽度像素  
     * @param bb     是否补白     */
     public final static void scale(String srcImageFile, String result, int height, int width, boolean bb) {            try {                double ratio = 0.0; // 缩放比例
               File f = new File(srcImageFile);
                BufferedImage bi = ImageIO.read(f);
                Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);//bi.SCALE_SMOOTH  选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。                // 计算比例
               if ((bi.getHeight() > height) || (bi.getWidth() > width)) {                   double   ratioHeight = (new Integer(height)).doubleValue()/ bi.getHeight();                   double   ratioWhidth = (new Integer(width)).doubleValue()/ bi.getWidth();                   if(ratioHeight>ratioWhidth){
                       ratio= ratioHeight;
                   }else{
                       ratio= ratioWhidth;
                   }
                    AffineTransformOp op = new AffineTransformOp(AffineTransform//仿射转换
                            .getScaleInstance(ratio, ratio), null);//返回表示剪切变换的变换
                    itemp = op.filter(bi, null);//转换源 BufferedImage 并将结果存储在目标 BufferedImage 中。                }                if (bb) {//补白
                   BufferedImage image = new BufferedImage(width, height,
                            BufferedImage.TYPE_INT_RGB);//构造一个类型为预定义图像类型之一的 BufferedImage。
                    Graphics2D g = image.createGraphics();//创建一个 Graphics2D,可以将它绘制到此 BufferedImage 中。
                    g.setColor(Color.white);//控制颜色
                    g.fillRect(0, 0, width, height);// 使用 Graphics2D 上下文的设置,填充 Shape 的内部区域。
                    if (width == itemp.getWidth(null))
                        g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                                itemp.getWidth(null), itemp.getHeight(null),
                                Color.white, null);                    else
                        g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                                itemp.getWidth(null), itemp.getHeight(null),
                                Color.white, null);
                    g.dispose();
                    itemp = image;
                }
                ImageIO.write((BufferedImage) itemp, "JPEG", new File(result));      //输出压缩图片
            } catch (IOException e) {
                e.printStackTrace();
            }
        }     /**
      * 裁剪图片方法
      * @param bufferedImage 图像源
      * @param startX 裁剪开始x坐标
      * @param startY 裁剪开始y坐标
      * @param endX 裁剪结束x坐标
      * @param endY 裁剪结束y坐标
      * @return
      */
     public static BufferedImage cropImage(BufferedImage bufferedImage, int startX, int startY, int endX, int endY) {            int width = bufferedImage.getWidth();            int height = bufferedImage.getHeight();            if (startX == -1) {
                startX = 0;
            }            if (startY == -1) {
                startY = 0;
            }            if (endX == -1) {
                endX = width - 1;
            }            if (endY == -1) {
                endY = height - 1;
            }
            BufferedImage result = new BufferedImage(endX - startX, endY - startY, 4);            for (int x = startX; x < endX; ++x) {                for (int y = startY; y < endY; ++y) {                    int rgb = bufferedImage.getRGB(x, y);
                    result.setRGB(x - startX, y - startY, rgb);
                }
            }            return result;
        }
}

复制代码

三、测试类:

复制代码

import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import com.etoak.util.ImgUtils;public class Test {    public static void main(String[] args) throws IOException {
        String path="C:/1.jpg";    //输入图片  测试要在C盘放一张图片1.jpg
        ImgUtils.scale("C:/1.jpg","C:/yasuo.jpg", 180, 240, true);//等比例缩放  输出缩放图片
        File newfile=new File("C:/yasuo.jpg");   
        BufferedImage bufferedimage=ImageIO.read(newfile);        int width = bufferedimage.getWidth();        int height = bufferedimage.getHeight();        //目标将图片裁剪成 宽240,高160
        if (width > 240) {                                                            /*开始x坐标              开始y坐标             结束x坐标                     结束y坐标*/
            bufferedimage=ImgUtils.cropImage(bufferedimage,(int) ((width - 240) / 2),0,(int) (width - (width-240) / 2),(int) (height)
                    );            if (height > 160) {
                bufferedimage=ImgUtils.cropImage(bufferedimage,0,(int) ((height - 160) / 2),240,(int) (height - (height - 160) / 2)
                        );
            }
        }else{            if (height > 160) {
                bufferedimage=ImgUtils.cropImage(bufferedimage,0,(int) ((height - 160) / 2),(int) (width),(int) (height - (height - 160) / 2)
                        );
            }
        }
        ImageIO.write(bufferedimage, "jpg", new File("C:/caijian.jpg"));    //输出裁剪图片    }
}

复制代码

  • 2019-12-06 10:47:29

    date-fns日期工具的使用方法详解

    isToday() 判断传入日期是否为今天 isYesterday() 判断传入日期是否为昨天 isTomorrow() 判断传入日期是否为 format() 日期格式化 addDays() 获得当前日期之后的日期 addHours() 获得当前时间n小时之后的时间点 addMinutes() 获得当前时间n分钟之后的时间 addMonths() 获得当前月之后n个月的月份 subDays() 获得当前时间之前n天的时间 subHours() 获得当前时间之前n小时的时间 subMinutes() 获得当前时间之前n分钟的时间 subMonths() 获得当前时间之前n个月的时间 differenceInYears() 获得两个时间相差的年份 differenceInWeeks() 获得两个时间相差的周数 differenceInDays() 获得两个时间相差的天数 differenceInHours() 获得两个时间相差的小时数 differenceInMinutes() 获得两个时间相差的分钟数

  • 2019-12-06 10:49:39

    npm 查看源 换源

    npm,cnpm,查看源,切换源,npm config set registry https://registry.npmjs.org

  • 2019-12-06 11:01:31

    npm发布包流程详解 有demo

    npm发布包步骤,以及踩过的坑(见红颜色标准): 1.注册npm账号,并完成Email认证(否则最后一步提交会报Email错误) 2.npm添加用户或登陆:npm adduser 或 npm login

  • 2019-12-06 13:16:18

    vue mixins组件复用的几种方式

    最近在做项目的时候,研究了mixins,此功能有妙处。用的时候有这样一个场景,页面的风格不同,但是执行的方法,和需要的数据非常的相似。我们是否要写两种组件呢?还是保留一个并且然后另个一并兼容另一个呢? 不管以上那种方式都不是很合理,因为组件写成2个,不仅麻烦而且维护麻烦;第二种虽然做了兼容但是页面逻辑造成混乱,必然不清晰;有没有好的方法,有那就是用vue的混合插件mixins。混合在Vue是为了提出相似的数据和功能,使代码易懂,简单、清晰。

  • 2019-12-06 13:26:30

    vue的mixins混入合并规则

    混入minxins:分发vue组件中可复用功能的灵活方式。混入对象可以包含任意组件选项。组件使用混入对象时,所有混入对象的选项将混入该组件本身的选项。

  • 2019-12-06 16:50:34

    Intellij idea 如何关闭无用的提示

    Linux:Settings —> Editor —> Inspections —> General —> Duplicated Code Mac:Preferences --> Editor —> Inspections —> General —> Duplicated Code fragment 将对应的勾去掉。

  • 2019-12-09 15:36:56

    神秘的 shadow-dom 浅析,shadow-root

    顾名思义, shadow-dom,直译的话就是 影子dom ?我觉得可以理解为潜藏在黑暗中的 DOM 结构,也就是我们无法直接控制操纵的 DOM 结构。前端同学经常用开发者工具的话,查看 DOM 结构的时候,肯定看到过下面这样的结构:

  • 2019-12-10 11:13:50

    前端实战-基于Nuxt的SVG使用

    虽然我们在日常开发的时候,在使用iview 或者element ui等组件时,通常会包含一些常用icon;但是在面对一些特定的需求时,或者自己想high一下,这些通用的icon并不能很好的满足我们。这个时候我们可能会拿到一些SVG适量图,但是怎么去使用这些矢量图呢。