当前位置: 首页 > 面试题库 >

将dpi元数据写入Java中的jpeg图像

陈宏胜
2023-03-14
问题内容

我试图以编程方式在Java中设置jpeg图像的dpi元数据。图像的来源是扫描仪,因此我从TWAIN获得了水平/垂直分辨率以及图像原始数据。我想保存此信息以获得更好的打印效果。

这是我到目前为止的代码。它将原始图像(byteArray)保存为JPEG文件,但忽略了我通过IIOMetadata指定的X /
Ydensity信息。有什么建议我做错了吗?

任何其他解决方案(第三方库等)也将受到欢迎。

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream

import org.w3c.dom.Element;    
import com.sun.imageio.plugins.jpeg.JPEGImageWriter;

public boolean saveJpeg(int[] byteArray, int width, int height, int dpi, String file)
{
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    WritableRaster wr = bufferedImage.getRaster();
    wr.setPixels(0, 0, width, height, byteArray);

    try
    {           
        // Image writer 
        JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpeg").next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(new File(file));
        imageWriter.setOutput(ios);

        // Compression
        JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
        jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
        jpegParams.setCompressionQuality(0.85f);

        // Metadata (dpi)
        IIOMetadata data = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(bufferedImage), jpegParams);
        Element tree = (Element)data.getAsTree("javax_imageio_jpeg_image_1.0");
        Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
        jfif.setAttribute("Xdensity", Integer.toString(dpi));
        jfif.setAttribute("Ydensity", Integer.toString(dpi));
        jfif.setAttribute("resUnits", "1"); // density is dots per inch

        // Write and clean up
        imageWriter.write(data, new IIOImage(bufferedImage, null, null), jpegParams);
        ios.close();
        imageWriter.dispose();
    }
    catch (Exception e)
    {
       return false;
    }

    return true;
}

谢谢!


问题答案:

此处未考虑的一些问题:

  1. 该树未直接映射到IOMetaData。要应用树中的数据,请在设置密度和栅格参数后添加以下调用:

    data.setFromTree("javax_imageio_jpeg_image_1.0", tree);
    
  2. 不要在写调用中将元数据用作第一个参数。请参阅JPEGImageWriter#write(IIOMetaData, IIOImage, ImageWriteParam)。如果streamMetaData不为NULL,将生成警告(WARNING_STREAM_METADATA_IGNORED)。

  3. 设置的元数据IOMetadataIOImage。这些元数据由JPEGImageWriter使用。正确的写调用是

    imageWriter.write(null, new IIOImage(F_scaledImg, null, data), jpegParams);
    


 类似资料:
  • 问题内容: 我正在尝试从.jpg文件中删除元数据,然后将其替换为空。谁能提供一个示例说明我该怎么做? 问题答案: 当您读取图像时,不会读取元数据。因此,只需读入并写回即可。

  • 我看过使用PDFBox基于图像DPI提取图像的代码,如下所示 在上面的代码中,我可以指定图像分辨率(150),同时从pdf中提取图像。更高的分辨率,我得到更大的图像作为回报。 现在,我想反转它的意思是在将图像写入PDF时指定图像的分辨率/dpi,但下面的代码没有提供指定dpi的选项吗?有谁能指引我在哪里失踪 在将图像写入pdf时,请告诉我在哪里可以传递分辨率/DPI参数(因为图像大于pdf页面大小

  • 我有一个设置,其中docker容器使用日志驱动程序来写入它们的日志。目前日志中的日志行被转发到主机上运行的rsyslog,但syslog行上的应用程序名称显示为。 作为一种解决方法,我想将日志元数据中的字段写入syslog中出现的行中,这样我就可以确定在主机的syslog被发送到syslog聚合服务器之后,哪个容器写入了哪一行。 有什么建议吗?

  • JPEG或PNG是否支持元数据/辅助数据的压缩? 到目前为止,我读到的所有内容都集中在图像压缩上,我找不到任何关于扩展数据压缩的内容。 大多数压缩软件似乎会移除元数据,但是否有可能将其压缩呢?

  • 问题内容: 背景:我正在为通讯程序编写一个相机应用程序。我无法随时将捕获的图像保存到永久磁盘。相机必须支持所有方向。我的实现是使用熟悉的Surfaceview示例。我使用Display类来检测方向并相应地旋转相机。在takePicture jpeg回调中,我从byte[]构造了一个位图,以解决我遇到的某些长宽比问题 问题描述:在某些设备上,以ROTATION_270(设备顺时针旋转90度)拍摄的构

  • 问题内容: 在我们的应用程序中,我们希望用户输入如下: 我想在单元测试中通过该部分,以便我可以恢复线程以执行其余代码。我如何从junit 写入内容? 问题答案: 你想要做的是使用的方法从。这将使您可以从junit 传递数据。