JAVA对于图片的花式操作(不定期更新)
MultipartFile 转 Base64字符串
/**
* MultipartFile文件转bash64字符串
*
* @param multiPartFile 文件流
* @param isPrefix 是否需要前缀
* @return
*/
public static String multiPartFileToBase64String(
MultipartFile multiPartFile,
boolean isPrefix) {
String baseStr = null;
BASE64Encoder encoder = new BASE64Encoder();
try {
baseStr = encoder.encode(multiPartFile.getBytes());
baseStr = baseStr.replaceAll("\r\n", "");
if (isPrefix) {
baseStr = "data:image/jpeg;base64," + baseStr;
}
} catch (IOException e) {
}
return baseStr;
}
图片url 转 Base64字符串
/**
* 图片URL转Base64编码
*
* @param imagePath 图片URL
* @param isPrefix 是否需要前缀
* @return Base64编码
*/
public static String imageUrlToBase64(String imagePath, boolean isPrefix) {
ByteArrayOutputStream outPut = new ByteArrayOutputStream();
byte[] data = new byte[1024];
InputStream inStream = null;
try {
// 创建URL
URL url = new URL(imagePath);
// 创建链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10 * 1000);
if (conn.getResponseCode() != 200) {
//连接失败/链接失效/图片不存在
return "fail";
}
inStream = conn.getInputStream();
int len = -1;
while ((len = inStream.read(data)) != -1) {
outPut.write(data, 0, len);
}
// 对字节数组Base64编码
byte[] encode = Base64.getEncoder().encode(outPut.toByteArray());
if (isPrefix) {
String res = String.format("%s%s", "data:image/jpeg;base64,", new String(encode));
return res;
}
return new String(encode);
} catch (Exception e) {
} finally {
try {
inStream.close();
} catch (Exception e) {
}
}
}
图片url 转 MultipartFile
/**
* 在线图片url转成MultipartFile对象
*
* @param url 图片url
* @return
*/
public static MultipartFile imgUrlToMultiPartFile(String url) {
URLConnection connection = null;
InputStream inputStream = null;
byte[] bytes = null;
try {
connection = new URL(url).openConnection();
inputStream = connection.getInputStream();
bytes = StreamUtils.copyToByteArray(inputStream);
} catch (Exception e) {
log.error(e.toString());
}
String contentType = connection.getContentType();
String[] contentTypes = contentType.split("/");
String filename = "file." + contentTypes[1];
return new ByteArrayMultipartFile(bytes, filename, contentType);
}
图片url 转 File流
/**
* url资源转化为file流
*
* @param url 图片url
* @return
*/
public static File urlToFile(URL url) {
InputStream is = null;
File file = null;
FileOutputStream fos = null;
try {
file = File.createTempFile("tmp", null);
URLConnection urlConn = null;
urlConn = url.openConnection();
is = urlConn.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[4096];
int length;
while ((length = is.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
return file;
} catch (Exception e) {
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
}
}
if (fos != null) {
try {
fos.close();
} catch (Exception e) {
}
}
}
}
base64图片 压缩
引入依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.20</version>
</dependency>
代码编写
/**
* 目标大小不可设置太过准确,也不可太小,例如:需要压缩至150k以下的图片,那就传入140或者100左右的一个值即可
*
* @param imgBase64 原图片base64,含不含前缀【data:image/jpeg;base64,】都可
* @param targetSize 压缩图片目标大小,默认100KB
* @param throwException 出错时是否报错
* @return 返回的base64内容不含【data:image/jpeg;base64,】前缀
*/
public static String compressPic(String imgBase64, int targetSize, boolean throwException){
if(StringUtils.isEmpty(imgBase64)){
log.error("imgBase64 param not null ......");
if(throwException){
throw new MixException(BusinessErrorEnum.BASE_PARAM_FORMAT);
}
}
targetSize = targetSize <= 0 ? 100 : targetSize;
String newBase64 = imgBase64;
InputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
if(imgBase64.startsWith("data:")){
imgBase64 = imgBase64.split(",")[1];
}
// 解码 Base64 图片数据
byte[] imageBytes = Base64.getDecoder().decode(imgBase64);
// 计算图片大小(KB)
float imageOriginalSize = (float) imageBytes.length / 1024;
log.info("--------------compressedImageBytes#imageOriginalSize(Byte) = {}", imageOriginalSize);
//图片大小已经比目标值小,直接返回原图base64
if(imageOriginalSize < targetSize){
return newBase64;
}
// 创建输出流,用于存储压缩后的图片数据
outputStream = new ByteArrayOutputStream();
int index = 0;
byte[] compressedImageBytes = imageBytes;
// 图片大小压缩比例
BigDecimal scale = new BigDecimal(1.0f);
float quality = targetSize / imageOriginalSize;
// 先进行质量压缩,如果质量压缩大小最终高于目标值,那就进行图片大小压缩
while (scale.floatValue() >= 0.1 && compressedImageBytes.length / 1024 > targetSize){
// 创建输入流,读取解码后的图片数据
inputStream = new ByteArrayInputStream(imageBytes);
outputStream.reset();
Thumbnails.of(inputStream)
.scale(scale.floatValue())
.outputFormat("jpg")
.outputQuality(quality)
.toOutputStream(outputStream);
// 获取压缩后的图片数据
compressedImageBytes = outputStream.toByteArray();
scale = scale.subtract(new BigDecimal(0.05f));
++index;
log.info("--------------compressedImageBytes#index = {},scale = {}, nowSize = {}", index, scale.floatValue(), compressedImageBytes.length / 1024);
}
byte[] encode = Base64.getEncoder().encode(compressedImageBytes);
newBase64 = new String(encode);
log.info("--------------compressedImageBytes#nowImgSize(Byte) = {}", compressedImageBytes.length / 1024);
}catch (Exception e){
log.error("compressPic business error:", e);
if(throwException){
throw new MixException(BusinessErrorEnum.BASE_SERVER_UNKNOWN);
}
}finally {
// 关闭流
try {
if(inputStream != null){
inputStream.close();
}
if(outputStream != null){
outputStream.close();
}
} catch (Exception e) {
log.error("compressPic close stream error:", e);
if(throwException){
throw new MixException(BusinessErrorEnum.BASE_SERVER_UNKNOWN);
}
}
}
return newBase64;
}
抠图
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;
import java.io.*;
@Slf4j
public class ImageUtil {
private final static String PNG = "png";
private final static String JPG = "jpg";
private final static String JPEG = "jpeg";
private final static long TWO_MB = 1024 * 1024 * 2;
/**
* 切割图片,以左上角坐标为起点,切割指定宽高的图片
* @param file
* @param faceDetectVo
* @return
*/
public static MultipartFile slicingImage(InputStream file, String fileType, FaceDetectVo faceDetectVo){
// 读取原始图片
Integer width = faceDetectVo.getW();
Integer high = faceDetectVo.getH();
Integer x = faceDetectVo.getX();
Integer y = faceDetectVo.getY();
try {
BufferedImage originalImage = ImageIO.read(file);
int maxWidth = originalImage.getWidth(); // 获取原图的宽度
int maxHigh= originalImage.getHeight(); // 获取原图的高度
Color backgroundColor = getDominantColor(originalImage); // 获取原图的背景色
// 校验参数
x = x > 0 ? x : 0;
y = y > 0 ? y : 0;
width = width > 0 ? width : 0;
high = high > 0 ? high : 0;
width = x + width > maxWidth ? maxWidth - x: width;
high = y + high > maxHigh ? maxHigh - y : high;
BufferedImage subImage = originalImage.getSubimage(x, y, width, high);
// 处理png格式的
if (PNG.equals(fileType)){
// 创建带背景颜色的新图像
BufferedImage imageWithBackground = new BufferedImage(width, high, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = imageWithBackground.createGraphics();
g2d.setColor(backgroundColor);
g2d.fillRect(0,0, width, high);
g2d.drawImage(subImage, 0, 0, null);
g2d.dispose();
MultipartFile multipartFile = convertBufferedImageToMultipartFile(subImage, "data.png", PNG);
// 如果把jpg的图片后缀手动改为png,读取文件流的时候会文件变大,这种情况给他改为jpg
if (multipartFile.getSize() > TWO_MB){
multipartFile = convertBufferedImageToMultipartFile(subImage, "data.jpg", JPG);
log.info("抠图大小大于2mb, 尝试转为jpg, 文件大小为: {}", multipartFile.getSize());
}
System.out.println("图片切分完成!");
return multipartFile;
}
// 处理jpg, jpeg格式的
// 创建带背景颜色的新图像
BufferedImage imageWithBackground = new BufferedImage(width, high, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = imageWithBackground.createGraphics();
g2d.setColor(backgroundColor);
g2d.fillRect(0,0, width, high);
g2d.drawImage(subImage, 0, 0, null);
g2d.dispose();
MultipartFile multipartFile = convertBufferedImageToMultipartFile(imageWithBackground, "data." + fileType, fileType);
System.out.println("图片切分完成!");
return multipartFile;
} catch (IOException e) {
log.error("图片切分失败!", e);
} catch (RasterFormatException e) {
log.info("切分坐标超出图片范围,请检查坐标设置。");
}
return null;
}
// 获取原图的背景色(可以改进为更复杂的算法)
private static Color getDominantColor(BufferedImage image) {
// 这里简单返回左上角像素的颜色作为背景色
return new Color(image.getRGB(0, 0));
}
private static MultipartFile convertBufferedImageToMultipartFile(BufferedImage image, String fileName, String fileType) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, fileType, baos);
InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
return new MultipartFile() {
@Override
public String getName() {
return fileName;
}
@Override
public String getOriginalFilename() {
return fileName;
}
@Override
public String getContentType() {
return "image/" + fileType;
}
@Override
public boolean isEmpty() {
return baos.size() == 0;
}
@Override
public long getSize() {
return baos.size();
}
@Override
public byte[] getBytes() throws IOException {
return baos.toByteArray();
}
@Override
public InputStream getInputStream() throws IOException {
return inputStream;
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
// 这里可以实现文件转移逻辑
}
};
}
public static String getFileType(MultipartFile file) {
String fileName = file.getOriginalFilename().toLowerCase();
if (fileName.endsWith(StringPool.DOT + PNG)) {
return PNG;
}
if (fileName.endsWith(StringPool.DOT + JPG)) {
return JPG;
}
if (fileName.endsWith(StringPool.DOT + JPEG)) {
return JPEG;
}else {
return PNG;
}
}
}
标签:return,String,url,不定期,new,JAVA,null,public,花式
From: https://blog.csdn.net/m0_63164811/article/details/143329507