有关 java 设置图片 DPI
作者:夜的第七章
- 2023-11-09 山西
本文字数:1976 字
阅读完需:约 6 分钟
背景:
java 端调用 python 算法修图接口后,返回了 base64 字符串,需要将 base64 字符串转图片,用文件流的方式写入图片会增大图片大小,不太明白当中为什么会增大,代码如下:
String base64String = "base64字符串";
BASE64Decoder decode = new BASE64Decoder();
byte[] imageBytes = decode.decodeBuffer(base64String);
FileOutputStream stream = new FileOutputStream("test.jpg");
stream.write(imageBytes);
stream.close();
复制代码
而用 ImageIO.wirte 来写入图片,不会增大图片大小,但输出的图片 dpi 会变为 96,可能是默认会设置为 96dpi,手动设置一下图片 dpi,代码如下:
public void base642img() {
//读取txt文件为String
String base64String = FileUtils.readFileToString(new File("D:\\tmp\\A0001\\1.1.1\\A0001-1.1.1-0004\\result\\test.txt"), "utf-8");
BASE64Decoder decode = new BASE64Decoder();
byte[] imageBytes = decode.decodeBuffer(base64String);
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(inputStream);
JpegDPIProcessor processor = new JpegDPIProcessor();
byte[] img = processor.process(image,300);
//将img字节写到本地
try (FileOutputStream outputStream = new FileOutputStream("D:\\tmp\\A0001\\1.1.1\\A0001-1.1.1-0004\\result\\test.jpg");){
outputStream.write(img);
}
}
复制代码
import lombok.SneakyThrows;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
public class JpegDPIProcessor {
private String formatName = "jpeg";
public byte[] process(BufferedImage image, int dpi) throws IOException {
for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
ImageWriter writer = iw.next();
ImageWriteParam writeParams = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParams);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
continue;
}
String metadataFormat = "javax_imageio_jpeg_image_1.0";
IIOMetadataNode root = new IIOMetadataNode(metadataFormat);
IIOMetadataNode jpegVariety = new IIOMetadataNode("JPEGvariety");
IIOMetadataNode markerSequence = new IIOMetadataNode("markerSequence");
IIOMetadataNode app0JFIF = new IIOMetadataNode("app0JFIF");
app0JFIF.setAttribute("majorVersion", "1");
app0JFIF.setAttribute("minorVersion", "2");
app0JFIF.setAttribute("thumbWidth", "0");
app0JFIF.setAttribute("thumbHeight", "0");
app0JFIF.setAttribute("resUnits", "01");
app0JFIF.setAttribute("Xdensity", String.valueOf(dpi));
app0JFIF.setAttribute("Ydensity", String.valueOf(dpi));
root.appendChild(jpegVariety);
root.appendChild(markerSequence);
jpegVariety.appendChild(app0JFIF);
metadata.mergeTree(metadataFormat, root);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageOutputStream stream = null;
try {
stream = ImageIO.createImageOutputStream(out);
writer.setOutput(stream);
writer.write(metadata, new IIOImage(image, null, metadata), writeParams);
} finally {
stream.close();
}
return out.toByteArray();
}
return null;
}
}
复制代码
使用 Java 原生的 jdk 即可实现设置图片 dpi
划线
评论
复制
发布于: 刚刚阅读数: 3
夜的第七章
关注
老鸟一枚 2015-10-21 加入
A story conference for a man without a story
评论