[TOC]
# 壓縮圖片
## 1. 不改變寬高
1. 通過改變像素只改變內容大小,不改變寬高
```
package net.aexit.zongjian.ent.common.utils;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ImageCompressUtil {
/**
* 壓縮圖片,修改像素尺寸不變
* @param imgBytes 字節
* @param qality 壓縮比例 0~1
* @param format 圖片格式
* @return 字節
* @throws IOException
*/
public static byte[] compressPictureByQality(byte[] imgBytes, float qality,String format) throws IOException {
BufferedImage src;
ByteArrayOutputStream outStream = null;
ImageWriter imgWrier;
ImageWriteParam imgWriteParams;
ByteArrayInputStream inputStream =null;
byte[] rtnByte = null;
try {
// 指定寫圖片的方式為 jpg
imgWrier = ImageIO.getImageWritersByFormatName(format).next();
imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(
null);
// 要使用壓縮,必須指定壓縮方式為MODE_EXPLICIT
imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
// 這里指定壓縮的程度,參數qality是取值0~1范圍內,
imgWriteParams.setCompressionQuality(qality);
imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
inputStream = new ByteArrayInputStream(imgBytes);
ColorModel colorModel = ImageIO.read(inputStream).getColorModel();// ColorModel.getRGBdefault();
imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(
colorModel, colorModel.createCompatibleSampleModel(32, 32)));
inputStream = new ByteArrayInputStream(imgBytes);
src = ImageIO.read(inputStream);
outStream = new ByteArrayOutputStream();
imgWrier.reset();
imgWrier.setOutput(ImageIO.createImageOutputStream(outStream));
// 調用write方法,就可以向輸入流寫圖片
imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);
rtnByte = outStream.toByteArray();
} finally {
if (outStream != null) {
outStream.close();
}
if (inputStream != null) {
inputStream.close();
}
}
return rtnByte;
}
public static void main(String args[]) throws Exception {
// ImageCompressUtil.saveMinPhoto("C:\\Users\\1\\Desktop\\Snapshots\\\\20180907_10.55.08_8068.jpg", "C:\\Users\\1\\Desktop\\Snapshots\\20180907_10.44.05_8068副本.jpg", 800, 1);
}
}
```
## 2. 改變寬高
```
package com.aixin.tuna.workflow.util;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class ImageCompressUtil {
/**
* 直接指定壓縮后的寬高:
* (先保存原文件,再壓縮、上傳)
* 壹拍項目中用于二維碼壓縮
* @param oldFile 要進行壓縮的文件全路徑
* @param width 壓縮后的寬度
* @param height 壓縮后的高度
* @param quality 壓縮質量
* @param smallIcon 文件名的小小后綴(注意,非文件后綴名稱),入壓縮文件名是yasuo.jpg,則壓縮后文件名是yasuo(+smallIcon).jpg
* @return 返回壓縮后的文件的全路徑
*/
public static String zipImageFile(String oldFile, int width, int height,
float quality, String smallIcon) {
if (oldFile == null) {
return null;
}
String newImage = null;
try {
/**對服務器上的臨時文件進行處理 */
Image srcFile = ImageIO.read(new File(oldFile));
/** 寬,高設定 */
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
String filePrex = oldFile.substring(0, oldFile.indexOf('.'));
/** 壓縮后的文件名 */
newImage = filePrex + smallIcon + oldFile.substring(filePrex.length());
/** 壓縮之后臨時存放位置 */
FileOutputStream out = new FileOutputStream(newImage);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
/** 壓縮質量 */
jep.setQuality(quality, true);
encoder.encode(tag, jep);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return newImage;
}
/**
* 保存文件到服務器臨時路徑(用于文件上傳)
* @param fileName
* @param is
* @return 文件全路徑
*/
public static String writeFile(String fileName, InputStream is) {
if (fileName == null || fileName.trim().length() == 0) {
return null;
}
try {
/** 首先保存到臨時文件 */
FileOutputStream fos = new FileOutputStream(fileName);
byte[] readBytes = new byte[512];// 緩沖大小
int readed = 0;
while ((readed = is.read(readBytes)) > 0) {
fos.write(readBytes, 0, readed);
}
fos.close();
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileName;
}
/**
* 等比例壓縮算法:
* 算法思想:根據壓縮基數和壓縮比來壓縮原圖,生產一張圖片效果最接近原圖的縮略圖
* @param srcURL 原圖地址
* @param deskURL 縮略圖地址
* @param comBase 壓縮基數
* @param scale 壓縮限制(寬/高)比例 一般用1:
* 當scale>=1,縮略圖height=comBase,width按原圖寬高比例;若scale<1,縮略圖width=comBase,height按原圖寬高比例
* @throws Exception
* @author shenbin
* @createTime 2014-12-16
* @lastModifyTime 2014-12-16
*/
public static void saveMinPhoto(String srcURL, String deskURL, double comBase,
double scale) throws Exception {
File srcFile = new java.io.File(srcURL);
Image src = ImageIO.read(srcFile);
int srcHeight = src.getHeight(null);
int srcWidth = src.getWidth(null);
int deskHeight = 0;// 縮略圖高
int deskWidth = 0;// 縮略圖寬
double srcScale = (double) srcHeight / srcWidth;
/**縮略圖寬高算法*/
if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
if (srcScale >= scale || 1 / srcScale > scale) {
if (srcScale >= scale) {
deskHeight = (int) comBase;
deskWidth = srcWidth * deskHeight / srcHeight;
} else {
deskWidth = (int) comBase;
deskHeight = srcHeight * deskWidth / srcWidth;
}
} else {
if ((double) srcHeight > comBase) {
deskHeight = (int) comBase;
deskWidth = srcWidth * deskHeight / srcHeight;
} else {
deskWidth = (int) comBase;
deskHeight = srcHeight * deskWidth / srcWidth;
}
}
} else {
deskHeight = srcHeight;
deskWidth = srcWidth;
}
BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //繪制縮小后的圖
FileOutputStream deskImage = new FileOutputStream(deskURL); //輸出到文件流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(deskImage);
encoder.encode(tag); //近JPEG編碼
deskImage.close();
}
public static void main(String args[]) throws Exception {
// ImageCompressUtil.zipImageFile("C:\\Users/*/\\1\\Desktop\\1.png", 1280, 1280, 1f, "-副本");
ImageCompressUtil.saveMinPhoto("C:\\Users\\1\\Desktop\\1.png", "C:\\Users\\1\\Desktop\\1-副本1.png", 500, 1);
}
}
```
- 計算機網絡
- 基礎_01
- tcp/ip
- http轉https
- Let's Encrypt免費ssl證書(基于haproxy負載)
- what's the http?
- 網關
- 網絡IO
- http
- 工具
- Git
- 初始本地倉庫并上傳
- git保存密碼
- Gitflow
- maven
- 1.生命周期命令
- 聚合與繼承
- 插件管理
- assembly
- 資源管理插件
- 依賴范圍
- 分環境打包
- dependencyManagement
- 版本分類
- 找不到主類
- 無法加載主類
- 私服
- svn
- gradle
- 手動引入第三方jar包
- 打包exe文件
- Windows
- java
- 設計模式
- 七大原則
- 1.開閉原則
- 2. 里式替換原則
- 3. 依賴倒置原則
- 4. 單一職責原則
- 單例模式
- 工廠模式
- 簡單工廠
- 工廠方法模式
- 抽象工廠模式
- 觀察者模式
- 適配器模式
- 建造者模式
- 代理模式
- 適配器模式
- 命令模式
- json
- jackson
- poi
- excel
- easy-poi
- 規則
- 模板
- 合并單元格
- word
- 讀取
- java基礎
- 類路徑與jar
- 訪問控制權限
- 類加載
- 注解
- 異常處理
- String不可變
- 跨域
- transient關鍵字
- 二進制編碼
- 泛型1
- 與或非
- final詳解
- Java -jar
- 正則
- 讀取jar
- map
- map計算
- hashcode計算原理
- 枚舉
- 序列化
- URLClassLoader
- 環境變量和系統變量
- java高級
- java8
- 1.Lambda表達式和函數式接口
- 2.接口的默認方法和靜態方法
- 3.方法引用
- 4.重復注解
- 5.類型推斷
- 6.拓寬注解的應用場景
- java7-自動關閉資源機制
- 泛型
- stream
- 時區的正確理解
- StringJoiner字符串拼接
- 注解
- @RequestParam和@RequestBody的區別
- 多線程
- 概念
- 線程實現方法
- 守護線程
- 線程阻塞
- 筆試題
- 類加載
- FutureTask和Future
- 線程池
- 同步與異步
- 高效簡潔的代碼
- IO
- ThreadLocal
- IO
- NIO
- 圖片操作
- KeyTool生成證書
- 壓縮圖片
- restful
- 分布式session
- app保持session
- ClassLoader.getResources 能搜索到的資源路徑
- java開發規范
- jvm
- 高并發
- netty
- 多線程與多路復用
- 異步與事件驅動
- 五種IO模型
- copy on write
- code style
- 布隆過濾器
- 筆試
- 數據庫
- mybatis
- mybatis與springboot整合配置
- pagehelper
- 分頁數據重復問題
- Java與數據庫之間映射
- 攔截器
- 攔截器應用
- jvm
- 堆內存測試
- 線程棧
- 直接內存
- 內存結構
- 內存模型
- 垃圾回收
- 調優
- 符號引用
- 運行參數
- 方法區
- 分帶回收理論
- 快捷開發
- idea插件
- 注釋模板
- git
- pull沖突
- push沖突
- Excel處理
- 圖片處理
- 合并單元格
- easypoi
- 模板處理
- 響應式編程
- reactor
- reactor基礎
- jingyan
- 規范
- 數據庫