java - java - 如何在保持物理大小的Java中重新采样图像?
问题描述
假设我有一个 144x144 像素的图像,ppi(每英寸像素数)为 144。所以我的图像实际上是一个 1x1 英寸的正方形。现在我想将其像素密度降低到 72 ppi,但仍保留其 1x1 平方英寸的物理尺寸。为了实现这一点,现在需要将图像的像素设置为 72x72 像素。我想只用这些输入来实现这一点:
- 图片
- 目标 ppi
这与ImageMagick中所做的非常相似,如下所示
convert -units PixelsPerInch original_144by144.jpg -resample resampled_72 72by72.jpg
上面的 ImageMagick 命令在内部进行重采样时会保留图像的物理尺寸。
我想在 Java 中做到这一点。关于如何去做的任何建议?
解决方案
我只是想让人们意识到每英寸像素(PPI) 与每英寸点数 (DPI) 不同。尽管这些术语经常用于指代同一事物,但它们是不同的,请阅读此处以获得更多见解。
我个人只会通过 Java 应用程序使用ImageMagick(它是免费和开源的),因为 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<String>) 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 也具有通过命令行的批处理功能。
推荐阅读
- postgresql - PostgreSQL。存储函数或查询改进
- java - 我有一个 Java 程序,上面写着“索引 1 超出长度 1 的范围”
- git - Kubernetes 集群上的 Gitlab - 无法使用 git 克隆或推送
- cython - 编写 cython 库的性能不佳
- python - Spyder Python 3.7 为什么有些方法在点后没有显示?
- python - 如何使用python中的where子句从firestore中的数组中删除元素
- laravel - 如果验证码不是来自请求,我应该把它放在哪里?
- c# - 如何在 JetBrains Rider 中允许不安全的代码?
- amazon-web-services - AWS TCO 计算器是否不再活动?
- android - 如果 APK SHA 与 Firebase 控制台中的 SHA 不匹配,是否阻止 Firebase 数据库(或 Auth)运行?