import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
public class FileUtils {
@Autowired
private FileConfigProperties fileConfigProperties;
public static void imageScale(MultipartFile sourceFile, File targetFile){
imageScale(sourceFile, targetFile, 375, 500, 1f);
}
public static void imageScale(File sourceFile, File targetFile){
imageScale(sourceFile, targetFile, 375, 500, 1f);
}
public static void imageScale(MultipartFile sourceFile, File targetFile, int width, int height, float quality){
try {
Thumbnails.of(sourceFile.getInputStream()).size(width, height).outputQuality(quality).toFile(targetFile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void imageScale(File sourceFile, File targetFile, int width, int height, float quality){
try {
Thumbnails.of(sourceFile).size(width, height).outputQuality(quality).toFile(targetFile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean checkImagePixel(MultipartFile multipartFile){
// 校验图片大小
int imageSize = (int) bytes2kb(multipartFile.getSize());
log.info("图片大小 -> {}", imageSize);
if (imageSize > 512){
return true;
}
// 校验图片像素
int width = 0;
int height = 0;
try {
BufferedImage bufferedImage = file2ImageBuffer(multipartFile.getInputStream());
width = bufferedImage.getWidth();
height = bufferedImage.getHeight();
} catch (IOException e) {
throw new BusinessException("获取图片像素失败");
}
log.info("图片像素,width -> {}, height -> {}", width, height);
if ((width * height) > (800 * 600)){
return true;
}
return false;
}
public static boolean checkImagePixel(File file){
if (file == null){
return false;
}
// 校验图片大小
int imageSize = (int) bytes2kb(file.length());
if (imageSize > 512){
return true;
}
// 校验图片像素
int width = 0;
int height = 0;
try {
BufferedImage bufferedImage = file2ImageBuffer(file);
width = bufferedImage.getWidth();
height = bufferedImage.getHeight();
} catch (Exception e) {
throw new BusinessException("获取图片像素失败");
}
if ((width * height) > (800 * 600)){
return true;
}
return false;
}
public static BufferedImage file2ImageBuffer(File file){
BufferedImage bi = null;
try {
bi = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
return bi;
}
public static BufferedImage file2ImageBuffer(InputStream inputStream){
BufferedImage bi = null;
try {
bi = ImageIO.read(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
return bi;
}
public static boolean checkIsImage(String fileSuffix){
List<String> imageType = new ArrayList<>(Arrays.asList("jpg","jpeg","png","bmp","gif"));
return imageType.contains(fileSuffix);
}
public static boolean checkIsImageByFileName(String fileName){
String fileNameSuffix = readFileNameSuffix(fileName);
return checkIsImage(fileNameSuffix);
}
/**
* 判断文件大小
*
* @param len
* 文件长度
* @param size
* 限制大小
* @param unit
* 限制单位(B,K,M,G)
* @return
*/
public boolean checkFileSize(Long len, int size, String unit) {
// long len = file.length();
double fileSize = 0;
if ("B".equals(unit.toUpperCase())) {
fileSize = (double) len;
} else if ("K".equals(unit.toUpperCase())) {
fileSize = (double) len / 1024;
} else if ("M".equals(unit.toUpperCase())) {
fileSize = (double) len / 1048576;
} else if ("G".equals(unit.toUpperCase())) {
fileSize = (double) len / 1073741824;
}
if (fileSize > size) {
return false;
}
return true;
}
/**
* 网络图片转换Base64的方法
*
* @param netImagePath
*/
private String netImageToBase64(String netImagePath) {
String strNetImageToBase64 = "";
final ByteArrayOutputStream data = new ByteArrayOutputStream();
try {
// 创建URL
URL url = new URL(netImagePath);
final byte[] by = new byte[1024];
// 创建链接
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
try {
InputStream is = conn.getInputStream();
// 将内容读取内存中
int len = -1;
while ((len = is.read(by)) != -1) {
data.write(by, 0, len);
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
strNetImageToBase64 = encoder.encode(data.toByteArray());
System.out.println("网络图片转换Base64:" + strNetImageToBase64);
// 关闭流
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return strNetImageToBase64;
}
/**
* 本地图片转换Base64的方法
*
* @param imgPath
*/
public String imageToBase64(String imgPath) {
byte[] data = null;
// 读取图片字节数组
try {
InputStream in = new FileInputStream(imgPath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
// 返回Base64编码过的字节数组字符串
System.out.println("本地图片转换Base64:" + encoder.encode(Objects.requireNonNull(data)));
return encoder.encode(Objects.requireNonNull(data));
}
public String base64ToUrl(String base64){
BASE64Decoder decoder = new BASE64Decoder();
String path = DateTimeUtil.buildLocalDateTimeToString_yyyy_MM(LocalDate.now());
String fileName = DateTimeUtil.buildLocalDateTimeToString_YYMMDDHHMMSS(LocalDateTime.now());
String suffix = RandomUtil.randomString(4);
String readUrl = null;
try {
byte[] bytes = decoder.decodeBuffer(base64);
StringBuilder buffer = new StringBuilder();
buffer.append(fileConfigProperties.getBaseWritePath())
.append(fileConfigProperties.getImagesPath())
.append(path);
File file = new File(buffer.toString());
if (!file.exists()) {
file.mkdirs();
}
buffer.append("/").append(fileName).append(suffix).append(".jpg");
OutputStream os = new FileOutputStream(buffer.toString());
os.write(bytes, 0, bytes.length);
os.flush();
os.close();
readUrl = new StringBuffer().append(fileConfigProperties.getBaseReadPath()).append(fileConfigProperties.getImagesPath())
.append(path).append("/").append(fileName).append(suffix).append(".jpg").toString();
log.info("base64图片下载url:{}",readUrl);
} catch (IOException e) {
e.printStackTrace();
}
return readUrl;
}
/***
* 删除文件
* @param file
*/
public static void deleteFile(File file){
File[] files = file.listFiles();
for(int i=0;i<files.length;i++){
if(files[i].isDirectory()){
deleteFile(files[i]);
}else{
files[i].delete();
}
}
file.delete();
}
/**
* 将获取到的字节数转换为KB,MB模式
* @param bytes
* @return
*/
public static float bytes2kb(long bytes){
BigDecimal fileSize = new BigDecimal(bytes);
BigDecimal kilobyte = new BigDecimal(1024);
return fileSize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
}
public static void checkImageSize(byte[] data){
int size = (int)bytes2kb(data.length);
if(size>500){
throw new BusinessException("图片不得大于500KB");
}
}
public static int readImageSize(byte[] data){
return (int)bytes2kb(data.length);
}
public static String readFileNameSuffix(String fileName) {
// split用的是正则,所以需要用 //. 来做分隔符
String[] split = fileName.split("\\.");
//注意判断截取后的数组长度,数组最后一个元素是后缀名
if (split.length > 1) {
return split[split.length - 1];
} else {
return "";
}
}
public static ByteArrayOutputStream cloneInputStream(InputStream input) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public synchronized static File modifyImageFormat(InputStream inputStream, String destPath, String formatName) {
File destFile = null;
try {
byte[] bytes = readInputStream(inputStream);
Image i = Toolkit.getDefaultToolkit().createImage(bytes);
PixelGrabber pg = new PixelGrabber(i, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth(), height = pg.getHeight();
final int[] RGB_MASKS = { 0xFF0000, 0xFF00, 0xFF };
final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);
DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
BufferedImage bufferedImg = new BufferedImage(RGB_OPAQUE, raster, false, null);
destFile = new File(destPath);
ImageIO.write(bufferedImg, formatName, destFile);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return destFile;
}
public synchronized static File modifyImageFormat(byte[] bytes, String destPath, String formatName) {
File destFile = null;
try {
Image i = Toolkit.getDefaultToolkit().createImage(bytes);
PixelGrabber pg = new PixelGrabber(i, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth();
int height = pg.getHeight();
final int[] RGB_MASKS = { 0xFF0000, 0xFF00, 0xFF };
final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);
DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
BufferedImage bufferedImg = new BufferedImage(RGB_OPAQUE, raster, false, null);
destFile = new File(destPath);
ImageIO.write(bufferedImg, formatName, destFile);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return destFile;
}
public static String getPicType(InputStream fis) {
//读取文件的前几个字节来判断图片格式
byte[] b = new byte[4];
try {
fis.read(b, 0, b.length);
String type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return "TYPE_JPG";
} else if (type.contains("89504E47")) {
return "TYPE_PNG";
} else if (type.contains("47494638")) {
return "TYPE_GIF";
} else if (type.contains("424D")) {
return "TYPE_BMP";
}else{
return "TYPE_UNKNOWN";
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static String getPicType(byte[] inputStreamBytes) {
//读取文件的前几个字节来判断图片格式
byte[] b = new byte[4];
try {
System.arraycopy(inputStreamBytes,0, b, 0, b.length);
String type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return "TYPE_JPG";
} else if (type.contains("89504E47")) {
return "TYPE_PNG";
} else if (type.contains("47494638")) {
return "TYPE_GIF";
} else if (type.contains("424D")) {
return "TYPE_BMP";
}else{
return "TYPE_UNKNOWN";
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将流转换为字节
* @param is
* @return
*/
public static byte[] readInputStream(InputStream is) {
/**
* 捕获内存缓冲区的数据,转换成字节数组
* ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据。
* 在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。
*/
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 创建字节数组 1024 = 1M
byte[] buffer = new byte[1024];
// 防止无限循环
int length = -1;
try {
// 循环写入数据到字节数组
while ((length = is.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, length);
}
// 强制刷新,扫尾工作,主要是为了,让数据流在管道的传输工程中全部传输过去,防止丢失数据
byteArrayOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
// 字节流转换字节数组
byte[] data = byteArrayOutputStream.toByteArray();
try {
// 关闭读取流
is.close();
// 关闭写入流
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = 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) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString().toUpperCase();
}
}
文件工具类FileUtils
最新推荐文章于 2023-10-07 17:08:17 发布