增加公共方法
This commit is contained in:
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@@ -19,7 +20,10 @@ public class PubUtils {
|
||||
* @param i 保留的位数
|
||||
* @param value double原值
|
||||
*/
|
||||
public static double doubleRound(int i, double value) {
|
||||
public static Double doubleRound(int i, Double value) {
|
||||
if (Objects.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal bp = new BigDecimal(value);
|
||||
return bp.setScale(i, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
@@ -30,7 +34,10 @@ public class PubUtils {
|
||||
* @param i 保留的位数
|
||||
* @param value double原值
|
||||
*/
|
||||
public static String doubleRoundStr(int i, double value) {
|
||||
public static String doubleRoundStr(int i, Double value) {
|
||||
if (Objects.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal bp = new BigDecimal(value);
|
||||
return bp.setScale(i, RoundingMode.HALF_UP).toPlainString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
package com.njcn.common.utils.images;
|
||||
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0
|
||||
* @data 2025/6/16 13:45
|
||||
*
|
||||
* 图片格式转换,目前主要用于BufferedImage转bmp、bmp转BIN
|
||||
*/
|
||||
public class ImageConverter {
|
||||
|
||||
/**
|
||||
* 将BufferedImage转换为BMP格式的字节数组
|
||||
* @param image BufferedImage对象
|
||||
* @return BMP格式的字节数组
|
||||
* @throws IOException 如果转换过程中发生IO错误
|
||||
*/
|
||||
public static byte[] convertToBMP(BufferedImage image) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
// 写入BMP文件头
|
||||
writeBMPHeader(baos, image.getWidth(), image.getHeight());
|
||||
|
||||
// 写入像素数据
|
||||
for (int y = image.getHeight() - 1; y >= 0; y--) {
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
int rgb = image.getRGB(x, y);
|
||||
// 写入BGR格式(BMP格式要求)
|
||||
// B
|
||||
baos.write(rgb & 0xFF);
|
||||
// G
|
||||
baos.write((rgb >> 8) & 0xFF);
|
||||
// R
|
||||
baos.write((rgb >> 16) & 0xFF);
|
||||
}
|
||||
// 行对齐(每行必须是4字节的倍数)
|
||||
int padding = (4 - (image.getWidth() * 3) % 4) % 4;
|
||||
for (int i = 0; i < padding; i++) {
|
||||
baos.write(0);
|
||||
}
|
||||
}
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将BMP格式的字节数组转换为BIN格式
|
||||
* @param bmpData BMP格式的字节数组
|
||||
* @return BIN格式的字节数组
|
||||
*/
|
||||
public static byte[] convertBMPToBIN(byte[] bmpData) {
|
||||
// 跳过BMP文件头(54字节)
|
||||
int offset = 54;
|
||||
int width = ByteBuffer.wrap(bmpData, 18, 4).order(ByteOrder.LITTLE_ENDIAN).getInt();
|
||||
int height = ByteBuffer.wrap(bmpData, 22, 4).order(ByteOrder.LITTLE_ENDIAN).getInt();
|
||||
|
||||
// 计算每行的字节数(包括对齐)
|
||||
int rowSize = ((width * 3 + 3) / 4) * 4;
|
||||
|
||||
// 创建BIN数据数组
|
||||
byte[] binData = new byte[width * height];
|
||||
int binIndex = 0;
|
||||
|
||||
// 转换像素数据
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int bmpIndex = offset + (height - 1 - y) * rowSize + x * 3;
|
||||
// 将BGR转换为灰度值
|
||||
int b = bmpData[bmpIndex] & 0xFF;
|
||||
int g = bmpData[bmpIndex + 1] & 0xFF;
|
||||
int r = bmpData[bmpIndex + 2] & 0xFF;
|
||||
// 使用加权平均计算灰度值
|
||||
int gray = (int) (0.299 * r + 0.587 * g + 0.114 * b);
|
||||
// 二值化(阈值设为128)
|
||||
binData[binIndex++] = (byte) (gray > 128 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return binData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将BufferedImage直接转换为BIN格式
|
||||
* @param image BufferedImage对象
|
||||
* @return BIN格式的字节数组
|
||||
* @throws IOException 如果转换过程中发生IO错误
|
||||
*/
|
||||
public static byte[] convertToBIN(BufferedImage image) throws IOException {
|
||||
byte[] bmpData = convertToBMP(image);
|
||||
return convertBMPToBIN(bmpData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入BMP文件头
|
||||
* @param out 输出流
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @throws IOException 如果写入过程中发生IO错误
|
||||
*/
|
||||
private static void writeBMPHeader(OutputStream out, int width, int height) throws IOException {
|
||||
// 文件头(14字节)
|
||||
out.write('B');
|
||||
out.write('M');
|
||||
writeInt(out, 54 + width * height * 3); // 文件大小
|
||||
writeInt(out, 0); // 保留
|
||||
writeInt(out, 54); // 数据偏移量
|
||||
|
||||
// 信息头(40字节)
|
||||
writeInt(out, 40); // 信息头大小
|
||||
writeInt(out, width); // 宽度
|
||||
writeInt(out, height); // 高度
|
||||
writeShort(out, 1); // 颜色平面数
|
||||
writeShort(out, 24); // 每像素位数
|
||||
writeInt(out, 0); // 压缩方式
|
||||
writeInt(out, width * height * 3); // 图像数据大小
|
||||
writeInt(out, 0); // 水平分辨率
|
||||
writeInt(out, 0); // 垂直分辨率
|
||||
writeInt(out, 0); // 使用的颜色数
|
||||
writeInt(out, 0); // 重要颜色数
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入一个整数(小端序)
|
||||
* @param out 输出流
|
||||
* @param value 要写入的整数
|
||||
* @throws IOException 如果写入过程中发生IO错误
|
||||
*/
|
||||
private static void writeInt(OutputStream out, int value) throws IOException {
|
||||
out.write(value & 0xFF);
|
||||
out.write((value >> 8) & 0xFF);
|
||||
out.write((value >> 16) & 0xFF);
|
||||
out.write((value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入一个短整数(小端序)
|
||||
* @param out 输出流
|
||||
* @param value 要写入的短整数
|
||||
* @throws IOException 如果写入过程中发生IO错误
|
||||
*/
|
||||
private static void writeShort(OutputStream out, int value) throws IOException {
|
||||
out.write(value & 0xFF);
|
||||
out.write((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将BufferedImage保存为BMP文件
|
||||
* @param image BufferedImage对象
|
||||
* @param filePath 保存路径
|
||||
* @throws IOException 如果保存过程中发生IO错误
|
||||
*/
|
||||
public static void saveAsBMP(BufferedImage image, String filePath) throws IOException {
|
||||
byte[] bmpData = convertToBMP(image);
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
||||
fos.write(bmpData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将BufferedImage保存为BIN文件
|
||||
* @param image BufferedImage对象
|
||||
* @param filePath 保存路径
|
||||
* @throws IOException 如果保存过程中发生IO错误
|
||||
*/
|
||||
public static void saveAsBIN(BufferedImage image, String filePath) throws IOException {
|
||||
byte[] binData = convertToBIN(image);
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
||||
fos.write(binData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将BMP数据保存为文件
|
||||
* @param bmpData BMP格式的字节数组
|
||||
* @param filePath 保存路径
|
||||
* @throws IOException 如果保存过程中发生IO错误
|
||||
*/
|
||||
public static void saveBMPToFile(byte[] bmpData, String filePath) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
||||
fos.write(bmpData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将BIN数据保存为文件
|
||||
* @param binData BIN格式的字节数组
|
||||
* @param filePath 保存路径
|
||||
* @throws IOException 如果保存过程中发生IO错误
|
||||
*/
|
||||
public static void saveBINToFile(byte[] binData, String filePath) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
||||
fos.write(binData);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user