import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
/**
* @author gyp
* @version 1.0
* @date 2019/9/20 10:39
*/
public final class ImageUtil {
private ImageUtil() {
}
/**
* 裁剪圖片並返回圖片的字節數組
*
* @param url 圖片的url
* @param formatName 圖片格式名 jpg\png\jpeg...
* @param x 起始點x
* @param y 起始點y
* @param w 裁剪寬度
* @param h 裁剪高度
* @return
* @throws IOException
*/
public static byte[] subToByteArray(URL url, String formatName, int x, int y, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(url);
buffer = buffer.getSubimage(x, y, w, h);
return toByteArray(buffer, formatName);
}
/**
* 裁剪圖片並返回圖片的字節數組
*
* @param input 圖片的輸入流
* @param formatName 圖片格式名 jpg\png\jpeg...
* @param x 起始點x
* @param y 起始點y
* @param w 裁剪寬度
* @param h 裁剪高度
* @return
* @throws IOException
*/
public static byte[] subToByteArray(InputStream input, String formatName, int x, int y, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(input);
buffer = buffer.getSubimage(x, y, w, h);
return toByteArray(buffer, formatName);
}
/**
* 裁剪圖片並返回圖片的字節數組
*
* @param file 圖片文件
* @param formatName 圖片格式名 jpg\png\jpeg...
* @param x 起始點x
* @param y 起始點y
* @param w 裁剪寬度
* @param h 裁剪高度
* @return
* @throws IOException
*/
public static byte[] subToByteArray(File file, String formatName, int x, int y, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(file);
buffer = buffer.getSubimage(x, y, w, h);
return toByteArray(buffer, formatName);
}
/**
* 根據比率裁剪圖片例如 3:2
*
* @param w 寬的比率因素 例如 3
* @param h 高的比率因素 例如 2
* @return
*/
public static BufferedImage subByRate(URL url, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(url);
return baseSubByRate(buffer, w, h);
}
/**
* 根據比率裁剪圖片例如 3:2
*
* @param formatName 圖片格式名 jpg\png\jpeg...
* @param w 寬的比率因素 例如 3
* @param h 高的比率因素 例如 2
* @return
*/
public static BufferedImage subByRate(InputStream input, String formatName, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(input);
return baseSubByRate(buffer, w, h);
}
/**
* 根據比率裁剪圖片例如 3:2
*
* @param w 寬的比率因素 例如 3
* @param h 高的比率因素 例如 2
* @return
*/
public static BufferedImage subByRate(File file, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(file);
return baseSubByRate(buffer, w, h);
}
private static BufferedImage baseSubByRate(BufferedImage buffer, int w, int h) throws IOException {
int imgWidth = buffer.getWidth();
int imgHeight = buffer.getHeight();
// 圖片的寬高比
BigDecimal imgRate = BigDecimal.valueOf(imgWidth).divide(BigDecimal.valueOf(imgHeight), 8, BigDecimal.ROUND_HALF_UP);
// 裁剪後寬高比
BigDecimal rate = BigDecimal.valueOf(w).divide(BigDecimal.valueOf(h), 8, BigDecimal.ROUND_HALF_UP);
int compare = imgRate.compareTo(rate);
if (compare > 0) {
// 如果圖片比例比裁剪比例大,則裁剪左右
int width = BigDecimal.valueOf(imgHeight).multiply(rate).intValue();
int x = (imgWidth - width) / 2;
return buffer.getSubimage(x, 0, width, imgHeight);
}
if (compare < 0) {
// 如果圖片比例比裁剪比例小,則裁剪上下
int height = BigDecimal.valueOf(imgWidth).divide(rate, 0, BigDecimal.ROUND_HALF_DOWN).intValue();
int y = (imgHeight - height) / 2;
return buffer.getSubimage(0, y, imgWidth, height);
}
return buffer;
}
/**
* 圖片轉byte數組
*
* @param buffer 圖片
* @param formatName 圖片格式名 jpg\png\jpeg...
* @return
* @throws IOException
*/
public static byte[] toByteArray(BufferedImage buffer, String formatName) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(buffer, formatName, outputStream);
return outputStream.toByteArray();
}
/**
* 填充顏色
*
* @param buffer 圖片
* @param color 顏色
* @param x 起始點x
* @param y 起始點y
* @param w 填充寬度
* @param h 填充高度
*/
public static void fillColor(BufferedImage buffer, Color color, int x, int y, int w, int h) {
Graphics2D graphics = buffer.createGraphics();
graphics.setPaint(color);
graphics.fillRect(x, y, w, h);
}
/**
* 填充圖片到指定比率
*
* @param url 圖片url
* @param color 填充顏色
* @param w 寬的比率因素 例如3
* @param h 高的比率因素 例如2
* @return
* @throws IOException
*/
public static BufferedImage fillByRate(URL url, Color color, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(url);
return baseFillByRate(buffer, color, w, h);
}
/**
* 填充圖片到指定比率
*
* @param input 圖片輸入流
* @param color 填充顏色
* @param w 寬的比率因素 例如3
* @param h 高的比率因素 例如2
* @return
* @throws IOException
*/
public static BufferedImage fillByRate(InputStream input, Color color, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(input);
return baseFillByRate(buffer, color, w, h);
}
/**
* 填充圖片到指定比率
*
* @param file 圖片文件
* @param color 填充顏色
* @param w 寬的比率因素 例如3
* @param h 高的比率因素 例如2
* @return
* @throws IOException
*/
public static BufferedImage fillByRate(File file, Color color, int w, int h) throws IOException {
BufferedImage buffer = ImageIO.read(file);
return baseFillByRate(buffer, color, w, h);
}
private static BufferedImage baseFillByRate(BufferedImage buffer, Color color, int w, int h) {
int imgWidth = buffer.getWidth();
int imgHeight = buffer.getHeight();
// 圖片的寬高比
BigDecimal imgRate = BigDecimal.valueOf(imgWidth).divide(BigDecimal.valueOf(imgHeight), 8, BigDecimal.ROUND_HALF_UP);
// 裁剪後寬高比
BigDecimal rate = BigDecimal.valueOf(w).divide(BigDecimal.valueOf(h), 8, BigDecimal.ROUND_HALF_UP);
int compare = imgRate.compareTo(rate);
if (compare > 0) {
// 如果圖片比例比填充比例大,則填充上下
int height = BigDecimal.valueOf(imgWidth).divide(rate, 0, BigDecimal.ROUND_HALF_UP).intValue();
BufferedImage bufferedImage = new BufferedImage(imgWidth, height, buffer.getType());
Graphics2D graphics = bufferedImage.createGraphics();
int topH = (height - imgHeight) / 2;
graphics.setPaint(color);
graphics.fillRect(0, 0, imgWidth, topH);
AffineTransform xform = new AffineTransform();
xform.translate(0, topH);
graphics.drawRenderedImage(buffer, xform);
graphics.fillRect(0, topH + imgHeight, imgWidth, height - topH - imgHeight);
return bufferedImage;
}
if (compare < 0) {
// 如果圖片比例比填充比例小,則填充左右
int width = BigDecimal.valueOf(imgHeight).multiply(rate).intValue();
BufferedImage bufferedImage = new BufferedImage(width, imgHeight, buffer.getType());
Graphics2D graphics = bufferedImage.createGraphics();
int leftW = (width - imgWidth) / 2;
graphics.fillRect(0, 0, leftW, imgHeight);
AffineTransform xform = new AffineTransform();
xform.translate(leftW, 0);
graphics.drawRenderedImage(buffer, xform);
graphics.fillRect(leftW + imgWidth, 0, width - leftW - imgWidth, imgHeight);
return bufferedImage;
}
return buffer;
}
}