Java图片压缩大小,图片缩放

添加依赖

  <!-- 图片缩略图 -->
            <dependency>
                <groupId>net.coobird</groupId>
                <artifactId>thumbnailator</artifactId>
                <version>0.4.8</version>
            </dependency>

Java压缩图片案例1

部分后缀图片会出现压缩失败

@Override
    @Transactional(rollbackFor = Throwable.class)
    public Picture uploadZip(MultipartFile file, String username) {
        String originalFilename = "";//文件名称
        // 文件保存路径
        String filePatha = pictureUrl;//等同  C:/Users/admin/Desktop/url/picture #本地图片地址
        String urlProduct = "";
        Picture picture = new Picture();
        try {
            File addFile = new File(filePatha);
            if (!addFile.exists()) {
                addFile.mkdirs();
            }
            //如果出现同名文件,文件名后面加随机数
            String findFfilePatha = filePatha + "/" + file.getOriginalFilename();
            File addNameFile = new File(findFfilePatha);
            if (!addNameFile.exists()) {
                originalFilename = FileUtil.getFileNameNoEx(file.getOriginalFilename())+"."+ FileUtil.getExtensionName(file.getOriginalFilename());
            }else{
                originalFilename = FileUtil.getFileNameNoEx(file.getOriginalFilename()) + System.currentTimeMillis() +"."+ FileUtil.getExtensionName(file.getOriginalFilename());

            }
            filePatha += "/" + originalFilename;//绝对路径
            urlProduct += "/" + originalFilename;//相对路径
            // 转存文件
            log.info("地址:" + filePatha);
            log.info("文件大小:" + new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");
            log.info("文件名" + originalFilename);
            File file_a = FileUtil.toFile(file);

            BigDecimal a = new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP);
            BigDecimal b = new BigDecimal (0.5);
            File file_b = new File(filePatha);
            if(a.compareTo(b) == 1){//a大于b,压缩图片
                //压缩图片
                Thumbnails.of(file_a.getAbsolutePath()).scale(1f).outputQuality(0.25f).toFile(file_b.getAbsolutePath());
            }else{
                Files.copy(file_a.toPath(),file_b.toPath());//不压缩直接拷贝
            }
            //如果出现同名文件,文件名后面加随机数
            //FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), new File(filePatha));
            //multipartFile.transferTo(new File(filePatha));
            //删除临时文件
            /*FileUtil.deleteFile(addFile);
            FileUtil.deleteFile(addNameFile);
            FileUtil.deleteFile(file_a);*/
        } catch (IOException e) {
            e.printStackTrace();
        }
        picture.setCreateTime(new Timestamp(System.currentTimeMillis()));
        picture.setSize(new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");
        picture.setUsername(username);
        picture.setFilename(originalFilename);
        picture.setUrl("/static/picture" + urlProduct);//存本地相对地址
        picture.setDelete(filePatha);
        pictureRepository.save(picture);
        return picture;
    }

Java压缩图片案例2

把图片转换成流文件

需要再添加个依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

ImageTool工具类

package me.zhengjie.utils;

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.stream.FileImageOutputStream;
import java.io.*;
import java.net.URL;

/**
 *  图片处理类
 *
 * @author honghe
 */
public class ImageTool {

    private static Logger logger = LoggerFactory.getLogger(
            ImageTool.class);

    private static final long DEFAULT_SIZE = 200 * 1024;


    /*public static void main(String[] args) {
        String picUrl = "C:/Users/admin/Desktop/url/picture/═╝╞м20.png";
        compress(picUrl,50);
    }*/

    /**
     * @param picUrl 图片地址
     * @param desFileSize 压缩大小
     */
    public static byte[] compress(String picUrl, long desFileSize,String fileNameCopy) {
        try {
            URL url = new URL(picUrl);
            byte[] imageBytes = IOUtils.toByteArray(url);
            if (imageBytes == null || imageBytes.length <= 0) {
                logger.error("图片资源加载失败,请检查链接地址!url:" + picUrl);
                throw new RuntimeException("图片资源加载失败,请检查链接地址!url:" + picUrl);
            }
            if (imageBytes.length <= desFileSize * 1024) {
                return imageBytes;
            }
            byte[] imageBytesCopy = imageBytes;
            double accuracy = getAccuracy(imageBytes.length / 1024);
            while (imageBytes.length > desFileSize * 1024) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
            }
            logger.info("【图片压缩】 | 图片原大小={}kb | 压缩后大小={}kb | url={}",
                    imageBytesCopy.length / 1024, imageBytes.length / 1024, picUrl);
            File file = new File(fileNameCopy);
            if(!file.exists()) {
                file.createNewFile();
            }
            FileWriter fileWriter =new FileWriter(file);
            fileWriter.write("");
            fileWriter.flush();
            fileWriter.close();

            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(fileNameCopy));
            imageOutput.write(imageBytes, 0, imageBytes.length);
            imageOutput.close();
            return imageBytes;
        } catch (Exception e) {
            logger.error("图片资源加载失败,请检查链接地址!url:" + picUrl);
            throw new RuntimeException("图片资源加载失败,请检查链接地址!url:" + picUrl);
        }
    }

    /**
     * 对图片byte[]进行base64
     */
    public static String base64ByPic(byte[] imageBatys) {
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(imageBatys);
    }

    /**
     * base64字符串转换成图片
     * 对字节数组字符串进行Base64解码并生成图
     *
     * @param imgStr      base64字符串
     * @param imgFilePath 图片存放路径
     * @dateTime 2018-02-23 14:42:17
     */
    public static boolean Base64ToImage(String imgStr, String imgFilePath) throws IOException {
        OutputStream out = null;
        if (StringUtils.isEmpty(imgStr)) {
            return false;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }
}

上传图片Controller和Service

    /**
     * 上传图片
     * @param file
     * @return
     * @throws Exception
     */
    @Log("上传图片")
    @PostMapping(value = "/picturesProduct")
    public ResponseEntity picturesProduct(@RequestParam MultipartFile file, String productUrl){
        Picture picture = pictureProductService.uploadZip(file,SecurityUtils.getUsername());
        Map map = new HashMap();
        map.put("errno",0);
        map.put("id",picture.getId());
        map.put("data",new String[]{picture.getUrl()});
        return new ResponseEntity(map,HttpStatus.OK);
    }



   /**
     * 上传图片
     * @param file
     * @param username
     * @return
     */
    @CacheEvict(allEntries = true)
    Picture uploadZip(MultipartFile file, String username);

Impl

 @Override
    @Transactional(rollbackFor = Throwable.class)
    public Picture uploadZip(MultipartFile file, String username) {
        String originalFilename = "";//文件名称
        String originalFilenameBackup = "";//文件名称备份
        // 文件保存路径
        String filePatha = pictureUrl;
        String filePathaBackup = pictureUrl;
        String urlProduct = "";
        Picture picture = new Picture();
        try {
            File addFile = new File(filePatha);
            if (!addFile.exists()) {
                addFile.mkdirs();
            }
            //如果出现同名文件,文件名后面加随机数
            String findFfilePatha = filePatha + "/" + file.getOriginalFilename();
            File addNameFile = new File(findFfilePatha);
            if (!addNameFile.exists()) {
                originalFilename = FileUtil.getFileNameNoEx(file.getOriginalFilename())+"."+ FileUtil.getExtensionName(file.getOriginalFilename());
                originalFilenameBackup = FileUtil.getFileNameNoEx(file.getOriginalFilename())+"Backup."+ FileUtil.getExtensionName(file.getOriginalFilename());
            }else{
                originalFilename = FileUtil.getFileNameNoEx(file.getOriginalFilename()) + System.currentTimeMillis() +"."+ FileUtil.getExtensionName(file.getOriginalFilename());
                originalFilenameBackup = FileUtil.getFileNameNoEx(file.getOriginalFilename()) + System.currentTimeMillis() +".Backup"+ FileUtil.getExtensionName(file.getOriginalFilename());

            }
            filePatha += "/" + originalFilename;//绝对路径
            filePathaBackup += "/" + originalFilenameBackup;//备份文件
            urlProduct += "/" + originalFilename;//相对路径
            // 转存文件
            log.info("地址:" + filePatha);
            log.info("文件大小:" + new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");
            log.info("文件名" + originalFilename);
            File file_a = FileUtil.toFile(file);

            BigDecimal a = new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP);
            BigDecimal b = new BigDecimal (0.3);//超过0.3M的图片进行压缩
            File file_b = new File(filePatha);
            if(a.compareTo(b) == 1){//a大于b,压缩图片
                //压缩图片
                //第一种方法 部分格式图片会压缩失败
                //Thumbnails.of(file_a.getAbsolutePath()).scale(1f).outputQuality(0.25f).toFile(file_b.getAbsolutePath());

                //第二种 流文件
                File file_c = new File(filePathaBackup);//备份数据
                Files.copy(file_a.toPath(),file_c.toPath());//不压缩直接拷贝
                ImageTool.compress("file:" + filePathaBackup,2000,file_b.getAbsolutePath());
                log.info("压缩成功:" + file_b.getAbsolutePath());
            }else{
                Files.copy(file_a.toPath(),file_b.toPath());//不压缩直接拷贝
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        picture.setCreateTime(new Timestamp(System.currentTimeMillis()));
        picture.setSize(new BigDecimal((double)file.getSize()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");
        picture.setUsername(username);
        picture.setFilename(originalFilename);
        picture.setUrl("/static/picture" + urlProduct);//存本地相对地址
        picture.setDelete(filePatha);
        pictureRepository.save(picture);
        return picture;
    }

按指定大小把图片进行缩放(会遵循原图高宽比例)

//按指定大小把图片进行缩和放(会遵循原图高宽比例) 
/此处把图片压成400×500的缩略图
Thumbnails.of(fromPic).size(400,500).toFile(toPic);//变为400*300,遵循原图比例缩或放到400*某个高度

按照指定比例进行缩小和放大

//按照比例进行缩小和放大
Thumbnails.of(fromPic).scale(0.2f).toFile(toPic);//按比例缩小
Thumbnails.of(fromPic).scale(2f);//按比例放大

按指定的大小进行缩放(不遵循原图比例)

//不按比例,就按指定的大小进行缩放
Thumbnails.of(fromPic).size(100, 100).keepAspectRatio(false).toFile(toPic);
//或者Thumbnails.of(fromPic).forceSize(100,100).toFile(toPic);

旋转图片

//旋转图片,rotate(角度),正数则为顺时针,负数则为逆时针
Thumbnails.of(fromPic).size(200,200).rotate(90).toFile(toPic);

图片尺寸不变,压缩图片文件大小

//图片尺寸不变,压缩图片文件大小outputQuality实现,参数1为最高质量
Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);

给图片加水印

//给图片加水印,watermark(位置,水印图,透明度)Positions.CENTER表示加在中间
Thumbnails.of(fromPic).size(400,400)
	.watermark(Positions.CENTER,ImageIO.read(waterPic),0.5f)
	.outputQuality(0.8f).toFile(toPic);

图片裁剪

//用sourceRegion()实现图片裁剪
//图片中心300*300的区域,Positions.CENTER表示中心,还有许多其他位置可选
Thumbnails.of(fromPic).sourceRegion(Positions.CENTER,300,300)
	.size(300,300).toFile(toPic);
//图片中上区域300*300的区域
Thumbnails.of(fromPic).sourceRegion(Positions.TOP_CENTER,300,300)
	.size(300,300).toFile(toPic);

转换图片格式 

格式由jpg变为png,图片大小没变。

//用outputFormat(图像格式)转换图片格式,保持原尺寸不变
Thumbnails.of(fromPic).scale(1f).outputFormat("png")
	.toFile("picture/png格式的图片.png");

输出成文件流OutputStream

//输出成文件流OutputStream
OutputStream os=new FileOutputStream(toPic);
Thumbnails.of(fromPic).size(120,120).toOutputStream(os);

输出成BufferedImage

//输出BufferedImage,asBufferedImage()返回BufferedImage
BufferedImage bi=Thumbnails.of(fromPic).size(120,120).asBufferedImage();
ImageIO.write(bi,"jpg",toPic);

压缩至指定图片尺寸,保持图片不变形,多余部分裁剪掉

		//压缩至指定图片尺寸(例如:横400高300),保持图片不变形,多余部分裁剪掉(这个是引的网友的代码)
		BufferedImage image = ImageIO.read(fromPic);
		Builder<BufferedImage> builder = null;
 
		int imageWidth = image.getWidth();
		int imageHeitht = image.getHeight();
		if ((float)300 / 400 != (float)imageWidth / imageHeitht) {
			if (imageWidth > imageHeitht) {
				image = Thumbnails.of(fromPic).height(300).asBufferedImage();
			} else {
				image = Thumbnails.of(fromPic).width(400).asBufferedImage();
			}
			builder = Thumbnails.of(image).sourceRegion(Positions.CENTER, 400, 300).size(400, 300);
		} else {
			builder = Thumbnails.of(image).size(400, 300);
		}
		builder.outputFormat("jpg").toFile(toPic);

参考作者:https://blog.csdn.net/chenleixing/article/details/44685817

发布了53 篇原创文章 · 获赞 768 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/tangcv/article/details/101292875