package cn.farboy.common.utils;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifIFD0Directory;
import lombok.Getter;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.Objects;
@Getter
public enum CutImageUtil {
FORMAT_750_500(750, 500),
FORMAT_600_600(600, 600);
CutImageUtil(int width, int height) {
this.width = width;
this.height = height;
}
private static final String prefix = "CutImageUtil";
private boolean sourceFromUrl = false;
private int width;
private int height;
private File source;
private File target;
private String format;
public CutImageUtil ofSource(File source) throws IOException {
if (notImage(source))
throw new IOException("This source file is NOT image");
this.source = source;
return this;
}
public CutImageUtil ofSource(String imageUrl) throws IOException {
if (StringUtils.isBlank(imageUrl))
throw new IOException("Please input image url");
this.source = getFileByUrl(imageUrl);
this.sourceFromUrl = true;
return this;
}
public CutImageUtil ofTarget(String suffix) throws IOException {
String realSuffix = suffix;
if (StringUtils.isBlank(realSuffix) || notSupportFormat(suffix)) {
realSuffix = ".jpeg";
}
if (!StringUtils.startsWith(realSuffix, "."))
realSuffix = "." + realSuffix;
this.format = StringUtils.substring(realSuffix, 1).toLowerCase();
this.target = File.createTempFile(prefix, realSuffix);
return this;
}
public File process() throws IOException {
Objects.requireNonNull(this.source, "please use ofSource() to set source image file");
if (Objects.isNull(target))
this.ofTarget(null);
Thumbnails.of(source)
.scale(this.getScale())
.outputQuality(1L)
.toFile(target);
Thumbnails.of(target)
.sourceRegion(Positions.CENTER, this.width, this.height)
.size(this.width, this.height)
//.outputFormatType(format)
.keepAspectRatio(false)
.outputQuality(1L)
.toFile(target);
if (this.sourceFromUrl)
this.source.deleteOnExit();
return target;
}
private boolean notImage(File source) {
try {
return Objects.isNull(ImageIO.read(source));
} catch (IOException ex) {
return true;
}
}
private boolean notSupportFormat(String suffix) {
if (StringUtils.isBlank(suffix)) return true;
return Arrays.stream(ImageIO.getWriterFormatNames()).noneMatch(f -> f.equalsIgnoreCase(suffix));
}
/*
* 计算图片的压缩比
*/
private double getScale() {
double scale = 1.000d;
int width;
int height;
try {
BufferedImage buffer = ImageIO.read(this.source);
try {
// 判断实际图片是否经过旋转
Metadata metadata = JpegMetadataReader.readMetadata(this.source);
Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
int orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
/**
* 3 旋转180度,长宽不变,图像倒置
* 6 旋转90度
* 8 旋转270度
*/
if (3 == orientation || 6 == orientation) {
width = buffer.getHeight();
height = buffer.getWidth();
} else {
width = buffer.getWidth();
height = buffer.getHeight();
}
} catch (JpegProcessingException | MetadataException e) {
width = buffer.getWidth();
height = buffer.getHeight();
}
if (width >= this.width && height >= this.height) {
if (width >= height) {
scale = (this.height * 1.00) / height;
} else {
scale = (this.width * 1.00) / width;
}
}
if (width >= this.width && height < this.height) {
scale = (this.height * 1.00) / height;
}
if (width < this.width && height >= this.height) {
scale = (this.width * 1.00) / width;
}
} catch (IOException e) {
e.printStackTrace();
}
return scale;
}
private File getFileByUrl(String imageUrl) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
BufferedOutputStream stream = null;
InputStream inputStream = null;
File file = null;
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36");
inputStream = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
String suffix = StringUtils.substring(imageUrl, imageUrl.lastIndexOf("."));
if (notSupportFormat(suffix)) {
suffix = ".jpg";
} else {
suffix = "." + suffix;
}
file = File.createTempFile(prefix, "." + suffix);
FileOutputStream fileOutputStream = new FileOutputStream(file);
stream = new BufferedOutputStream(fileOutputStream);
stream.write(outStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) inputStream.close();
if (stream != null) stream.close();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
}

分享之前写的剪切图片工具
Scroll Down© 本文著作权归作者所有,转载前请务必署名