ImageUtil图片工具: 压缩/格式转换等
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ImageUtil图片工具: 压缩/格式转换等相关的知识,希望对你有一定的参考价值。
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by niewj on 2018/9/10.
*/
public class ImgUtil {// @TODO
private static Logger logger = LoggerFactory.getLogger(ImgUtil.class);
public static final String JPG = "jpg";
public static final String GIF = "gif";
public static final String PNG = "png";
public static final String BMP = "bmp";
public static final int K = 1024;
public static final String TYPE_UNKNOWN = "unknown";
/**
* png格式图片转为jpg格式
*
* @param pngFile
* @return
*/
public static File convert2Jpg(File pngFile) {
// #0. 判空
if (pngFile == null || !pngFile.exists() || !pngFile.isFile() || !pngFile.canRead()) {
return null;
}
File jpgFile = null;
BufferedImage image;
try {
//#1. read image file
image = ImageIO.read(pngFile);
String parentPath = pngFile.getParent();
logger.info(ImgUtil.getPicType(new FileInputStream(pngFile)));
// #2. create a blank, RGB, same width and height, and a white background
BufferedImage newBufferedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
// #3. create image filename
long currentMillis = System.currentTimeMillis();
jpgFile = new File(parentPath, currentMillis + ".jpg");
// write to jpeg file
ImageIO.write(newBufferedImage, "jpg", jpgFile);
logger.info("Done");
} catch (IOException e) {
e.printStackTrace();
}
return jpgFile;
}
/**
* 旋转图片
*
* @param sourceFile 原图片
* @param degrees 旋转度数
* @throws IOException
*/
public static void rotate(File sourceFile, double degrees) throws IOException {
Thumbnails.of(sourceFile)
.rotate(degrees)//旋转度数
.scale(1)//缩放比例
.toFile(sourceFile);
}
/**
* 根据文件流判断图片类型
*
* @param fis
* @return jpg/png/gif/bmp
*/
public static String getPicType(FileInputStream fis) {
//读取文件的前几个字节来判断图片格式
byte[] b = new byte[4];
try {
fis.read(b, 0, b.length);
String type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return JPG;
} else if (type.contains("89504E47")) {
return PNG;
} else if (type.contains("47494638")) {
return GIF;
} else if (type.contains("424D")) {
return BMP;
} else {
return TYPE_UNKNOWN;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* byte数组转换成16进制字符串
*
* @param src
* @return
*/
private static String bytesToHexString(byte[] src) {
StringBuilder sBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
sBuilder.append(0);
}
sBuilder.append(hv);
}
return sBuilder.toString();
}
/**
* @param srcFile 待压缩的源文件
* @param desFileSize 限制的文件大小,单位Kb
* @param scale 压缩比例(0, 1.0]
*/
public static void commpressPicForScale(File srcFile, long desFileSize, double scale) {
try {
// #0. 获取文件类型,根据内容而不是后缀名
String type = getPicType(new FileInputStream(srcFile));
// #1. 判空
if (srcFile == null || !srcFile.exists() || !srcFile.isFile()) {
return;
}
// #2.输出大小
long len = srcFile.length();
logger.info("源图片:" + srcFile.getAbsolutePath() + ",大小:" + len / K + "kb");
// #3. 递归方法压缩
compressImage(type, srcFile, desFileSize, scale);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据照片类型、精确度,上限大小,压缩指定照片
*
* @param type 照片类型:jpg/png (1. type是根据文件的内容定的,而不是名字后缀值; 2. 除了jpg,其他都按照png处理)
* @param srcFile 源文件和目标文件:用的同一个
* @param desFileSize 目标值限制大小,单位Kb
* @param scale 压缩比:(0,1.0]
*/
private static void compressImage(String type, File srcFile, long desFileSize, double scale) {
if (srcFile == null || !srcFile.exists() || !srcFile.isFile()) {
logger.error("_n_待压缩源文件不合要求:srcFile={}", srcFile);
return;
}
try {
long fileSize = srcFile.length();
// 1、判断大小,如果小于500kb,不压缩;如果大于等于500kb,压缩:递归结束条件
if (fileSize <= desFileSize * K) {
return;
}
// 2. jpg格式有不失真的压缩方式;png的没有;
if (JPG.equalsIgnoreCase(type)) {
logger.info("jpg_file_compress:{}", srcFile.getAbsoluteFile());
Thumbnails.of(srcFile).scale(1.0f).outputQuality(scale).toFile(srcFile);
} else { // 其他图片类型,一律按照PNG格式缩放
logger.info("png_file_compress:{}", srcFile.getAbsoluteFile());
Thumbnails.of(srcFile).scale(scale).toFile(srcFile);
}
// 3. 记录下压缩后的大小
logger.info("compressing...{}kb", srcFile.length() / K);
// 4. 递归调用,直到大小符合要求
compressImage(type, srcFile, desFileSize, scale);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取base64字符串
*
* @param file
* @return
*/
public static String getImageBase64(File file) {
FileInputStream inputFile = null;
byte[] buffer = new byte[0];
try {
// #1. Base64输入流
inputFile = new FileInputStream(file);
buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
} catch (IOException e) {
e.printStackTrace();
} finally { // 用完后删除文件
deleteUploadedFile(file);
}
return new BASE64Encoder().encode(buffer);
}
/**
* 返回之前,把生成的文件删除掉
*
* @param file
*/
public static void deleteUploadedFile(File file) {
// 上传完文件之后,照片或视频文件删除掉
if (file != null && file.exists()) {
logger.info("file deleting: ", file.getAbsolutePath());
file.delete();
}
}
// private static String getImageBase64(String imageId) {
// File orgFile = FtpHelper.getFile(imageId);
// File file = renameFile(orgFile);
// ImageUtil.commpressPicForScale(file, 500, 0.9d); // 压缩照片
// Assert.assertion(file != null, ResponseCodeEnum.INTERNAL_HANDLE_ERROR, "file is not exit");
// FileInputStream inputFile = null;
// byte[] buffer = new byte[0];
// try {
// inputFile = new FileInputStream(file);
// buffer = new byte[(int) file.length()];
// inputFile.read(buffer);
// inputFile.close();
// } catch (Exception e) {
// LOGGER.error("Exception->
{}", e);
// throw new ThirdPartException(ResponseCodeEnum.INTERNAL_HANDLE_ERROR, StringMsg.fmtMsg("*"));
// } finally { // 用完后删除文件
// FtpHelper.deleteUploadedFile(file);
// FtpHelper.deleteUploadedFile(orgFile);
// }
// return new BASE64Encoder().encode(buffer);
// }
public static void main(String[] args) throws FileNotFoundException {
// File f2 = new File("E:\chrome_download\1.png");
// String type2 = ImageUtil.getPicType(new FileInputStream(f2));
// System.out.println("type2=" + type2);
//// ImageUtil.compressImage(type2, f2, 500, 0.9d);
// File pngFile = new File("C:\Users\weijun.nie\Desktop\thinkstats\test2.png");
// File jpgFile = convert2Jpg(pngFile);
// System.out.println(jpgFile.getAbsolutePath());
System.out.printf("%02X", 125);
}
}
以上是关于ImageUtil图片工具: 压缩/格式转换等的主要内容,如果未能解决你的问题,请参考以下文章