【JAVA秒会技术之玩转图片】图片下载和等比或指定大小压缩快速实现

JAVA图片下载等比或指定大小压缩工具类

话不多,直接上代码:

package com.netease.test;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import org.apache.commons.lang.StringUtils;
/**
 * 图片万能操作工具类
 * <p>Title: ImgUtils</p>
 * @author  Liyan
 * @date    2017年4月14日 下午2:59:42
 */
public class ImgUtils {

    private static BufferedOutputStream bos;

    /**
     * 根据图片url下载到本地
     * <p>Title: downLoadByUrl</p>
     * @author Liyan
     * @date   2017年4月14日 下午3:04:36
     * @param imgUrl 图片地址
     * @param location 下载后保存的地址。如"C:\\"
     * @param imgName 下载后保存的名称。如"a.jpg"
     * @return Boolean true 成功;false 失败
     */
    public static Boolean downLoadByUrl(String imgUrl, String location, String imgName) {
    	try {
        	//图片的url
        	if (StringUtils.isEmpty(imgUrl) || StringUtils.isEmpty(location) || StringUtils.isEmpty(imgName)) {
				return false;
			}
        	//设置图片下载后的保存位置及图片名称
        	File file = new File(location, imgName);
            InputStream inputStream = ImgUtils.getInputStreamByGet(imgUrl);
            ImgUtils.saveData(inputStream, file);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 等比缩放图片(按高度或宽度)
     * <p>Title: equalRatioResizeImage</p>
     * @author Liyan
     * @date   2017年4月14日 下午4:53:33
     * @param srcImgPath 原始照片的磁盘位置
     * @param distImgPath 目标照片的磁盘位置
     * @param width 宽度(单位像素) 注意:和height只能填一个,都填写默认按宽度计算
     * @param height 高度(单位像素) 注意:和width只能填一个,都填写默认按宽度计算
     * @return Boolean true 成功;false 失败
     */
    public static Boolean equalRatioResizeImage (String srcImgPath, String distImgPath, int newWidth, int newHeight){
    	try {
    		//参数校验
    		if (StringUtils.isEmpty(srcImgPath) || StringUtils.isEmpty(distImgPath)) {
    			return false;
			}
    		//获取图片原始尺寸
	    	Image srcFile = ImageIO.read(new File(srcImgPath));
	        int w = srcFile.getWidth(null);
	        int h = srcFile.getHeight(null);
	        double bili;
	        if(newWidth>0){
	            bili=newWidth/(double)w;
	            newHeight = (int) (h*bili);
	        }else{
	            if(newHeight>0){
	                bili=newHeight/(double)h;
	                newWidth = (int) (w*bili);
	            }
	        }
    		return ImgUtils.resizeImage(srcImgPath, distImgPath, newWidth, newHeight);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    }  

    /**
     * 压缩图片(指定尺寸)
     * <p>Title: resizeImage</p>
     * @author Liyan
     * @date   2017年4月14日 下午3:31:10
     * @param srcImgPath 原始照片的磁盘位置
     * @param distImgPath 目标照片的磁盘位置
     * @param width 宽度(单位像素)
     * @param height 高度(单位像素)
     * @return Boolean true 成功;false 失败
     */
    public static Boolean resizeImage (String srcImgPath, String distImgPath, int width, int height){
        try {
			String subfix = "jpg";
	        subfix = srcImgPath.substring(srcImgPath.lastIndexOf(".")+1,srcImgPath.length());
	        File srcFile = new File(srcImgPath);
	        Image srcImg = ImageIO.read(srcFile);
	        BufferedImage buffImg = null;
	        if(subfix.equals("png")){
	            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
	        }else{
	            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	        }
	        Graphics2D graphics = buffImg.createGraphics();
	        graphics.setBackground(Color.WHITE);
	        graphics.setColor(Color.WHITE);
	        graphics.fillRect(0, 0, width, height);
	        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
	        Image scaledInstance = srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);
	        graphics.drawImage(scaledInstance, 0, 0, null);
	        ImageIO.write(buffImg, subfix, new File(distImgPath));
	        return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    }  

	/**
     * 通过get请求得到读取器响应数据的数据流
     * <p>Title: getInputStreamByGet</p>
     * @author Liyan
	 * @throws IOException
	 * @throws MalformedURLException
     * @date   2017年4月14日 下午2:54:25
     */
    private static InputStream getInputStreamByGet(String url) throws MalformedURLException, IOException {
    	HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setReadTimeout(5000);
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");

        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            InputStream inputStream = conn.getInputStream();
            return inputStream;
        }
        return null;
    }

    /**
     * 将服务器响应的数据流存到本地文件
     * <p>Title: saveData</p>
     * @author Liyan
     * @throws IOException
     * @date   2017年4月14日 下午2:54:44
     */
    private static void saveData(InputStream is, File file) throws IOException {
    	BufferedInputStream bis = new BufferedInputStream(is);
    	bos = new BufferedOutputStream(new FileOutputStream(file));
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
            bos.flush();
        }
    }

    /**
     * 测试
     * <p>Title: main</p>
     * @author Liyan
     * @date   2017年4月14日 下午2:54:53
     */
    public static void main(String[] args) {
    	//根据图片url下载到本地
    	Boolean b1 = ImgUtils.downLoadByUrl("https://nos.netease.com/nim/MTAzODg1MQ==/bmltYV8yMjI1NDAwOThfMTQ5MDMzNjIwMTU0OV9mZjM0MzUzMC1jZTk0LTRkNDItYjJlZS1lNWFlYWE0MTJjZmU=?imageView&interlace=1&crop=0_0_1512_1653", "C://", "mydog.jpg");
        if (b1) {
        	System.out.println("测试【根据图片url下载到本地】成功");
		}
        //测试指定尺寸压缩图片
        Boolean b2 = ImgUtils.resizeImage("C:\\mydog.jpg","C:\\compressDog.jpg",302,330);
        if (b2) {
        	System.out.println("测试【压缩图片】成功");
		}
        //测试按宽度等比压缩
        Boolean b3 = ImgUtils.equalRatioResizeImage("C:\\mydog.jpg","C:\\compressDog2.jpg",151,0);
        if (b3) {
        	System.out.println("测试【按高度等比压缩】成功");
		}

    }
}

运行结果:

mydog.jpg



compressDog.jpg



compressDog2.jpg



PS:这是博主家养的小狗叫“胖胖”,~~~

时间: 2024-08-23 18:41:11

【JAVA秒会技术之玩转图片】图片下载和等比或指定大小压缩快速实现的相关文章

【JAVA秒会技术之玩转多线程】多线程那些事儿(一)

多线程那些事儿(一)     现在只要出去面试,关于"Java多线程"的问题,几乎没有一家单位不问的,可见其重要性.于是博主抽空研究了一下,确实很有意思!以下是我综合整理了网上的各种资料,和个人的一些理解,写的一篇总结博文,仅供学习.交流. (一)多线程的概念         多线程的概念,简单理解:一个进程运行时产生了不止一个线程.         进程的概念,简单理解:正在运行的程序的实例. 两者之间的关系:进程就是线程的容器. (二)多线程的好处         使用多线程可以提

【JAVA秒会技术之玩转SQL】MySQL优化技术(一)

MySQL优化技术(一)         开发的路上,总会碰到一些老系统,越用越慢."慢"的原因也许有很多,但是,博主个人觉得,数据库的设计和sql语句写的好坏,对系统效率的影响是最直接,最显而易见的!所以,学习一下MySQL的优化,还是很有必要的.当然,博主能力有限,没那么多经验,更多的是"道听途说"和"纸上谈兵".如有不正之处,望大神开后给予指正,不胜感激! (一)MySQL优化技术概述 ①表的设计合理化(符合3NF,即符合"三范式

【JAVA秒会技术之玩转SQL】MySQL优化技术(二)

MySQL优化技术(二) [前文连接]MySQL优化技术(一) (五)常用SQL优化 1.默认情况,在使用group by 分组查询时,会先分组,其后还会默认对组内其他条件进行默认的排序,可能会降低速度.这与在查询中指定order by col1, col2类似. 如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by null禁止排序. 例子:   2.尽量使用左连接(或右连接)来替代普通多表联查.因为使用JOIN,MySQL不需要在内存中创建临时表.    s

【JAVA秒会技术之玩转高效分页】EasyUI + PageHelper实现分页

 EasyUI + PageHelper实现分页 一.EasyUI页面分页 页面逻辑:页面初始化时,通过jquery easyui的DataGrid(数据表格)的url属性异步加载,返回指定的json格式数据,在通过pagination属性,展示分页工具栏.   表现层分析: 请求URL:/XXX/list 请求参数:Integer page.Integer rows(easyui分页控件请求的参数),其中page默认为1. 返回数据:json格式的数据(easyui分页控件请求的返回值JSON

【JAVA秒会技术之玩搞定GC】GC算法与种类

GC算法与种类 (一)GC的概念 GC,指Ganbage Collection 垃圾回收器.GC的算法主要分为四类:引用计数法.标记清除.标记压缩.复制算法.下面将对这几种算法进行逐一说明. (二)GC的算法--引用计数法 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1.只要对象A的引用计数器的值为0,则对象A就不可能再被使用.   引用计数法的问题: (1)引用和去引用伴随着加法和减法,影响性能: (2)很难处理循环引

【JAVA秒会技术之图片上传】基于Nginx及FastDFS,完成图片的上传及展示

基于Nginx及FastDFS,完成商品图片的上传及展示 一.传统图片存储及展示方式      存在问题: 1)大并发量上传访问图片时,需要对web应用做负载均衡,但是会存在图片共享问题 2)web应用服务器的存储空间有限,它是web应用服务器,而不是存储服务器. 3)web应用服务器的本身的io读写性能不高,图片上传下载时,速度偏慢 4)web应用服务器访问图片时,由于图片内容较大,并发量大的时候,会占用web应用服务器的带宽,这样该web应用服务器的其他功能就会受到较大的影响.    解决方

【JAVA秒会技术之搞定BLOB数据类型】如何读取及展示数据库中BLOB类型的图片

如何读取及展示数据库中BLOB类型的图片    [前言]最近在做某一需求时,需要从Oracle数据库读取图片.本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字"二进制图片读取及展示",发现有很多"抄来抄去"的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是"不明所以".     最后,花了近2个小时,耐心研究了一下,终于成功.于是总结如下,供大家参考,也

【JAVA秒会技术之秒杀面试官】JavaSE常见面试题(四)

[前言]别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 --   [下载]本人刚学习Java时总结的一些JavaSE常见面试题,偶尔在电脑中翻出,重新整理一下分享给需要的人,主要针对初级程序员.想要PDF完整版下载的,评论里留言留下你的邮箱! 61.同步代码块与同步函数的区别? 答:(1)同步代码块:位置比较灵活,锁对象可以任意对象,但必须是同一对象.格式:              

【JAVA秒会技术之多线程】多线程java.util.concurrent详解

一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源. 2.Java标准库提供了进程和线程相关的API,进程主要包括表示进程的jav