【问题标题】:How to resample an image in java maintaining it physical size?java - 如何在Java中重新采样图像以保持其物理尺寸?
【发布时间】:2019-07-01 09:24:45
【问题描述】:

假设我有一个 144x144 像素的图像,ppi(每英寸像素数)为 144。所以我的图像实际上是一个 1x1 英寸的正方形。现在我想将其像素密度降低到 72 ppi,但仍保留其 1x1 平方英寸的物理尺寸。为了实现这一点,现在需要将图像的像素设置为 72x72 像素。我想只用这些输入来实现这一点:

  • 图像
  • 目标 ppi

这与ImageMagick中所做的非常相似,如下所示

convert -units PixelsPerInch original_144by144.jpg -resample resampled_72 72by72.jpg

上面的 ImageMagick 命令在内部进行重采样时会保留图像的物理尺寸。

我想用 Java 来做这件事。有什么建议吗?

【问题讨论】:

    标签: java imagemagick


    【解决方案1】:

    我只是想让人们意识到 每英寸像素数 (PPI) 与 每英寸点数 (DPI) 不同。尽管这些术语经常用于指代同一事物,但它们是不同的Read here for more insight

    我个人只会在 Java 应用程序中使用 ImageMagick(它是免费的,open source),因为 ImageMagick 作为命令行应用程序工作得很好,例如:

    String imageMagickLocation = "D:\\ImageMagick-7.0.8-Q16\\magick.exe";
    String sourceImagePath = "C:\\Users\\DevilsHnd\\Pictures\\MyImage.png";
    String destinationPath = "C:\\Users\\DevilsHnd\\Pictures\\New_MyImage.png"; 
    int desiredPPI = 72;
    String commandLineString = imageMagickLocation + " convert -units PixelsPerInch \"" 
                             + sourceImagePath + "\" -resample " + desiredPPI + " \"" 
                             + destinationPath + "\""; 
    
    List<String> list = runCMD(commandLineString);
    
    /* Display any results from the call to the runCMD() 
       method. If ImageMagick is successful then there 
       should be nothing (the List should be empty).  */
    if (!list.isEmpty()) {
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
    

    下面提供的 runCMD() 方法允许您的应用程序像通过 Windows“命令提示符”窗口一样运行命令行应用程序:

    /**
     * This method is specifically designed for running the Microsoft Windows CMD 
     * command prompt and having the results that would normally be displayed within 
     * a Command Prompt Window placed into a string List Interface instead.<br><br>
     * <p>
     * <b>Example Usage:</b><pre>
     *       {@code 
     *          List<String> list = runCMD("/C dir");
     *          for (int i = 0; i < list.size(); i++) {
     *              System.out.println(list.get(i));
     *          }
     *       } </pre>
     *
     * @param commandString (String) The command string to pass to the Command
     *                      Prompt. You do not need to place "cmd" within your
     *                      command string because it is applied automatically.
     *                      As a matter of fact if you do it is automatically
     *                      removed.<br> 
     *
     * @return (List&lt;String&gt;) A string List containing the results of
     *         the processed command.
     */
    public List<String> runCMD(String commandString) {
        if (commandString.toLowerCase().startsWith("cmd ")) {
            commandString = commandString.substring(4);
        }
        List<String> result = new ArrayList<>();
        try {
            Process p = Runtime.getRuntime().exec("cmd /C " + commandString);
            try (BufferedReader in = new BufferedReader(
                    new InputStreamReader(p.getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    result.add(line);
                }
            }
            p.destroy(); // Kill the process
            return result;
        }
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "<html>IO Error during processing of runCMD()!"
                                        + "<br><br>" + e.getMessage() + "</html>",
                                          "runCMD() Method Error", JOptionPane.WARNING_MESSAGE);
            return null;
        }
    }
    

    使用 ImageMagick 将图像转换为每英寸 72 像素 (PPI) 的工作速度相对较快,但是将 PPI 设置为高于原始源 PPI 可能需要更长的时间,具体取决于差异。无论你做什么,都不要做一些疯狂的事情,比如将图像转换为 2000 PPI,除非你有一台具有大量内存的超级计算机(ImageMagick 会尝试这样做)。事实上,您可能希望安装保护措施来防止转换不合理的 PPI 值。

    ImageMagick 将特定图像重新采样为 72 PPI 的典型命令行操作是:

    D:\ImagMagick\magick.exe convert -units PixelsPerInch "C:\Pictures\MyImageName1.png" -resample 72 "C:\Pictures\MyImageName2.png"
    
                                O R
    
    D:\ImagMagick\magick.exe convert -units PixelsPerInch "C:\Pictures\MyImageName1.png" -resample 72 "C:\Pictures\MyImageName2.jpg"
    

    注意两个转换调用之间的目标文件扩展名更改。源和目标文件路径和/或文件名用引号括起来,以防其中包含一个或多个空格。

    此外,您可以轻松地修改内容以执行批量图像文件转换。我相信 ImageMagick 也可以通过命令行进行批处理。

    【讨论】:

    • 感谢 DevilsHnd。尽管由于我无法控制的原因,我一直在寻找纯 Java 解决方案:)
    猜你喜欢
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2014-07-03
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多