Java图片压缩大小,图片缩放
生活随笔
收集整理的這篇文章主要介紹了
Java图片压缩大小,图片缩放
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
添加依賴(lài)
<!-- 圖片縮略圖 --><dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency>Java壓縮圖片案例1
部分后綴圖片會(huì)出現(xiàn)壓縮失敗
//壓縮至范圍(50 壓縮到50KB)@Value(value = "${jeecg.path.image-comprssion-to}")private Integer imageComprssionTo;//上傳文件路徑(win D://opt//upFiles Linux /tang/upload)@Value(value = "${jeecg.path.upload}")private String uploadpath;@Override@Transactional(rollbackFor = Throwable.class)public AiFileStorage uploadZip(String fileName) {String originalFilename = "";//文件名稱(chēng)String filePatha = uploadpath;String filePathaBackup = uploadpath;AiFileStorage aiFileStorage = new AiFileStorage();try {File addFile = new File(filePatha);if (!addFile.exists()) {addFile.mkdirs();}String findFfilePatha = filePatha + "/" + fileName;File file = new File(findFfilePatha);File savefile;//服務(wù)器上相同名稱(chēng)的文件,后面拼接 _compress + iint i = -1;do {i++;savefile = new File(filePatha + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + "_compress" + (i == 0 ? "" : i)+ fileName.substring(fileName.indexOf(".")));originalFilename = fileName.substring(0, fileName.lastIndexOf(".")) + "_compress" + (i == 0 ? "" : i) + fileName.substring(fileName.indexOf("."));} while (savefile.exists());filePatha += "/" + originalFilename;//絕對(duì)路徑filePathaBackup += "/" + fileName;//源文件log.info("地址:" + filePatha);log.info("文件大小:" + new BigDecimal((double)file.length()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");log.info("文件名" + originalFilename);BigDecimal a = new BigDecimal((double)file.length()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP);Integer productCode = imageComprssionTo;//圖片壓縮范圍 超出的壓縮BigDecimal b = new BigDecimal(StringUtils.getM(productCode));File file_b = new File(filePatha);if(a.compareTo(b) == 1){//a大于b,壓縮圖片 a 源文件大小 b 壓縮至大小//壓縮圖片F(xiàn)ile file_c = new File(filePathaBackup);Files.copy(file.toPath(),file_b.toPath());Files.copy(file.toPath(),file_c.toPath());ImageTool.compress("file:" + filePathaBackup,productCode,file_b.getAbsolutePath());}else{Files.copy(file.toPath(),file_b.toPath());}aiFileStorage.setCreateTime(new Timestamp(System.currentTimeMillis()));aiFileStorage.setSize(file_b.length()/ 1024+" KB");aiFileStorage.setType(2);aiFileStorage.setSuffix(FileUtil.getExtensionName(file_b.getName()));aiFileStorage.setName(file_b.getName());aiFileStorage.setUrl(originalFilename);aiFileStorageService.save(aiFileStorage);return aiFileStorage;} catch (NoSuchFileException e) {e.printStackTrace();throw new BadRequestException("文件不存在");} catch (IOException e) {e.printStackTrace();}return new AiFileStorage();}文件記錄實(shí)體類(lèi)
package org.jeecg.modules.ai.entity;import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.Date; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors;/*** @Description: 文件存儲(chǔ)* @Date: 2021-01-13* @Version: V1.0*/ @Data @TableName("ai_file_storage") @Accessors(chain = true) @EqualsAndHashCode(callSuper = false) @ApiModel(value="ai_file_storage對(duì)象", description="文件存儲(chǔ)") public class AiFileStorage implements Serializable {private static final long serialVersionUID = 1L;/**主鍵*/@TableId(type = IdType.ASSIGN_ID)@ApiModelProperty(value = "主鍵")private String id;/**創(chuàng)建人*/@ApiModelProperty(value = "創(chuàng)建人")private String createBy;/**上傳或同步的時(shí)間*/@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@ApiModelProperty(value = "上傳或同步的時(shí)間")private Date createTime;/**文件名稱(chēng)*/@Excel(name = "文件名稱(chēng)", width = 15)@ApiModelProperty(value = "文件名稱(chēng)")private String name;/**文件大小*/@Excel(name = "文件大小", width = 15)@ApiModelProperty(value = "文件大小")private String size;/**文件類(lèi)型:私有或公開(kāi)(1,私 2.共)*/@Excel(name = "文件類(lèi)型:私有或公開(kāi)(1,私 2.共)", width = 15)@ApiModelProperty(value = "文件類(lèi)型:私有或公開(kāi)(1,私 2.共)")private Integer type;/**文件url*/@Excel(name = "文件url", width = 15)@ApiModelProperty(value = "文件url")private String url;/**文件后綴*/@Excel(name = "文件后綴", width = 15)@ApiModelProperty(value = "文件后綴")private String suffix; }FileUtil工具類(lèi)
package org.jeecg.modules.ai.utils;import cn.hutool.core.util.IdUtil; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException; import java.text.DecimalFormat;/*** File工具類(lèi),擴(kuò)展 hutool 工具包* @author 億校云* @date 2018-12-27*/ public class FileUtil extends cn.hutool.core.io.FileUtil {/*** 定義GB的計(jì)算常量*/private static final int GB = 1024 * 1024 * 1024;/*** 定義MB的計(jì)算常量*/private static final int MB = 1024 * 1024;/*** 定義KB的計(jì)算常量*/private static final int KB = 1024;/*** 格式化小數(shù)*/private static final DecimalFormat DF = new DecimalFormat("0.00");/*** MultipartFile轉(zhuǎn)File* @param multipartFile* @return*/public static File toFile(MultipartFile multipartFile){// 獲取文件名String fileName = multipartFile.getOriginalFilename();// 獲取文件后綴String prefix="."+getExtensionName(fileName);File file = null;try {// 用uuid作為文件名,防止生成的臨時(shí)文件重復(fù)file = File.createTempFile(IdUtil.simpleUUID(), prefix);// MultipartFile to FilemultipartFile.transferTo(file);} catch (IOException e) {e.printStackTrace();}return file;}/*** 刪除* @param files*/public static void deleteFile(File... files) {for (File file : files) {if (file.exists()) {file.delete();}}}/*** 獲取文件擴(kuò)展名* @param filename* @return*/public static String getExtensionName(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot >-1) && (dot < (filename.length() - 1))) {return filename.substring(dot + 1);}}return filename;}/*** Java文件操作 獲取不帶擴(kuò)展名的文件名* @param filename* @return*/public static String getFileNameNoEx(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot >-1) && (dot < (filename.length()))) {return filename.substring(0, dot);}}return filename;}/*** 文件大小轉(zhuǎn)換* @param size* @return*/public static String getSize(int size){String resultSize = "";if (size / GB >= 1) {//如果當(dāng)前Byte的值大于等于1GBresultSize = DF.format(size / (float) GB) + "GB ";} else if (size / MB >= 1) {//如果當(dāng)前Byte的值大于等于1MBresultSize = DF.format(size / (float) MB) + "MB ";} else if (size / KB >= 1) {//如果當(dāng)前Byte的值大于等于1KBresultSize = DF.format(size / (float) KB) + "KB ";} else {resultSize = size + "B ";}return resultSize;} }Java壓縮圖片案例2
把圖片轉(zhuǎn)換成流文件
需要再添加個(gè)依賴(lài)
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version> </dependency>ImageTool工具類(lèi)
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;/*** 圖片處理類(lèi)** @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("圖片資源加載失敗,請(qǐng)檢查鏈接地址!url:" + picUrl);throw new RuntimeException("圖片資源加載失敗,請(qǐng)檢查鏈接地址!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("圖片資源加載失敗,請(qǐng)檢查鏈接地址!url:" + picUrl);throw new RuntimeException("圖片資源加載失敗,請(qǐng)檢查鏈接地址!url:" + picUrl);}}/*** 對(duì)圖片byte[]進(jìn)行base64*/public static String base64ByPic(byte[] imageBatys) {// 對(duì)字節(jié)數(shù)組Base64編碼BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(imageBatys);}/*** base64字符串轉(zhuǎn)換成圖片* 對(duì)字節(jié)數(shù)組字符串進(jìn)行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) {// 調(diào)整異常數(shù)據(jù)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();}}}/*** 自動(dòng)調(diào)節(jié)精度(經(jīng)驗(yàn)數(shù)值)** @param size 源圖片大小* @return 圖片壓縮質(zhì)量比*/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 = "";//文件名稱(chēng)String originalFilenameBackup = "";//文件名稱(chēng)備份// 文件保存路徑String filePatha = pictureUrl;String filePathaBackup = pictureUrl;String urlProduct = "";Picture picture = new Picture();try {File addFile = new File(filePatha);if (!addFile.exists()) {addFile.mkdirs();}//如果出現(xiàn)同名文件,文件名后面加隨機(jī)數(shù)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;//絕對(duì)路徑filePathaBackup += "/" + originalFilenameBackup;//備份文件urlProduct += "/" + originalFilename;//相對(duì)路徑// 轉(zhuǎn)存文件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);//超過(guò)0.3M的圖片進(jìn)行壓縮File file_b = new File(filePatha);if(a.compareTo(b) == 1){//a大于b,壓縮圖片//壓縮圖片//第一種方法 部分格式圖片會(huì)壓縮失敗//Thumbnails.of(file_a.getAbsolutePath()).scale(1f).outputQuality(0.25f).toFile(file_b.getAbsolutePath());//第二種 流文件File file_c = new File(filePathaBackup);//備份數(shù)據(jù)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);//存本地相對(duì)地址picture.setDelete(filePatha);pictureRepository.save(picture);return picture;}?
?
?
按指定大小把圖片進(jìn)行縮放(會(huì)遵循原圖高寬比例)
//按指定大小把圖片進(jìn)行縮和放(會(huì)遵循原圖高寬比例) /此處把圖片壓成400×500的縮略圖 Thumbnails.of(fromPic).size(400,500).toFile(toPic);//變?yōu)?00*300,遵循原圖比例縮或放到400*某個(gè)高度按照指定比例進(jìn)行縮小和放大
//按照比例進(jìn)行縮小和放大 Thumbnails.of(fromPic).scale(0.2f).toFile(toPic);//按比例縮小 Thumbnails.of(fromPic).scale(2f);//按比例放大按指定的大小進(jìn)行縮放(不遵循原圖比例)
//不按比例,就按指定的大小進(jìn)行縮放 Thumbnails.of(fromPic).size(100, 100).keepAspectRatio(false).toFile(toPic); //或者Thumbnails.of(fromPic).forceSize(100,100).toFile(toPic);旋轉(zhuǎn)圖片
//旋轉(zhuǎn)圖片,rotate(角度),正數(shù)則為順時(shí)針,負(fù)數(shù)則為逆時(shí)針 Thumbnails.of(fromPic).size(200,200).rotate(90).toFile(toPic);圖片尺寸不變,壓縮圖片文件大小
//圖片尺寸不變,壓縮圖片文件大小outputQuality實(shí)現(xiàn),參數(shù)1為最高質(zhì)量 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()實(shí)現(xiàn)圖片裁剪 //圖片中心300*300的區(qū)域,Positions.CENTER表示中心,還有許多其他位置可選 Thumbnails.of(fromPic).sourceRegion(Positions.CENTER,300,300).size(300,300).toFile(toPic); //圖片中上區(qū)域300*300的區(qū)域 Thumbnails.of(fromPic).sourceRegion(Positions.TOP_CENTER,300,300).size(300,300).toFile(toPic);轉(zhuǎn)換圖片格式?
格式由jpg變?yōu)閜ng,圖片大小沒(méi)變。
//用outputFormat(圖像格式)轉(zhuǎn)換圖片格式,保持原尺寸不變 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),保持圖片不變形,多余部分裁剪掉(這個(gè)是引的網(wǎng)友的代碼)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
總結(jié)
以上是生活随笔為你收集整理的Java图片压缩大小,图片缩放的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 撤回的消息服务器还可以看到,微信消息被撤
- 下一篇: Unity_视频背景