日常开发中,会遇到图片处理,比如图片分割等,以下工具类可以将图片进行横向,纵向分割,可自定义分割。
package com.zx.test.common.utils;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
/**
* 图像处理工具类
*
* @author
* Create on 2023/9/11
*/
@Slf4j
public class ImageCorpUtils {
public static final int INT_HUNDRED = 100;
/**
* 图片等分分割
*
* @param inputBytes 图片的二进制数据
* @param widthSplits 图片横向分割成多少份,最少1份
* @param heightSplits 图片纵向分割成多少份,最少1份
* @return
*/
public static byte[][] split(byte[] inputBytes, int widthSplits, int heightSplits) throws IOException {
return split(inputBytes, widthSplits, heightSplits, null, null);
}
/**
* 图片自定义比例分割
*
* @param inputBytes 图片的二进制数据
* @param widthSplits 图片横向分割成多少份,最少1
* @param heightSplits 图片纵向分割成多少份,最少1
* @param splitWidthArray 分割图片的宽度数组,即每个分割的图片的宽度比例,取值0-100,总和为100
* @param splitHeightArray 分割图片的高度数组,即每个分割的图片的高度比例,取值0-100,总和为100
* @return
* @throws IOException
*/
public static byte[][] split(byte[] inputBytes, int widthSplits, int heightSplits, int[] splitWidthArray, int[] splitHeightArray) throws IOException {
byte[][] splitImages = new byte[widthSplits * heightSplits][];
widthSplits = widthSplits <= 0 ? 1 : widthSplits;
heightSplits = heightSplits <= 0 ? 1 : heightSplits;
//如果未传入分割数据,填充默认等分数组
if (splitWidthArray == null) {
splitWidthArray = new int[widthSplits];
for (int i = 0; i < widthSplits; i++) {
splitWidthArray[i] = (100 - sum(splitWidthArray)) / (widthSplits - i);
}
}
if (splitHeightArray == null) {
splitHeightArray = new int[heightSplits];
for (int i = 0; i < heightSplits; i++) {
splitHeightArray[i] = (100 - sum(splitHeightArray)) / (heightSplits - i);
}
}
if (splitWidthArray.length != widthSplits || sum(splitWidthArray) != INT_HUNDRED) {
throw new IllegalArgumentException("splitWidthArray is not right");
}
if (splitHeightArray.length != heightSplits || sum(splitHeightArray) != INT_HUNDRED) {
throw new IllegalArgumentException("splitHeightArray is not right");
}
BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(inputBytes));
for (int i = 0; i < widthSplits; i++) {
for (int j = 0; j < heightSplits; j++) {
int splitWidth = originalImage.getWidth() * splitWidthArray[i] / INT_HUNDRED;
int splitHeight = originalImage.getHeight() * splitHeightArray[j] / INT_HUNDRED;
int x = i == 0 ? 0 : originalImage.getWidth() * sum(splitWidthArray, i) / INT_HUNDRED;
int y = j == 0 ? 0 : originalImage.getHeight() * sum(splitHeightArray, j) / INT_HUNDRED;
log.info("裁剪图片:x->{};y->{},splitWidth->{},splitHeight->{}", x, y, splitWidth, splitHeight);
byte[] crop = crop(originalImage, x, y, splitWidth, splitHeight);
splitImages[(i * (heightSplits) + j)] = crop;
}
}
return splitImages;
}
public static byte[] crop(BufferedImage image, int x, int y, int cropWidth, int cropHeight) throws IOException {
BufferedImage subImage = image.getSubimage(x, y, cropWidth, cropHeight);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(subImage, "png", byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return byteArray;
}
public static int sum(int[] array) {
return sum(array, array.length);
}
public static int sum(int[] array, int index) {
if (index <= 0 || index >= array.length) {
index = array.length;
}
int sum = 0;
for (int i = 0; i < index; i++) {
sum += array[i];
}
return sum;
}
}