写点什么

有关 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

用户头像

老鸟一枚 2015-10-21 加入

A story conference for a man without a story

评论

发布
暂无评论
有关java设置图片DPI_夜的第七章_InfoQ写作社区