修改 事实证明,第二个片段实际上正在工作,但是由于某些原因,有问题的图像在我的IDE(IntelliJ IDEA)中仍然无法正确显示。
我正在尝试读取图像,放置水印并将其保存在其他文件夹中,下面的代码可以很好地完成工作,但是它会随意调整图像的方向。
try {
final Image image = ImageIO.read(file);
int w = ((BufferedImage) image).getWidth();
int h = ((BufferedImage) image).getHeight();
final BufferedImage finalImage =
new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
//Graphics2D g = finalImage.createGraphics();
Graphics2D g = (Graphics2D) finalImage.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(watermark, 0, 0, null);
g.dispose();
File outputFile = new File("watermarked/" + folderName + "/" + file.getName());
outputFile.mkdirs();
ImageIO.write(finalImage, "jpg", outputFile);
} catch (IOException e) {
// TODO: notify client
e.printStackTrace();
}
经过一番阅读,我了解到ImageIO.read(...)
不会保持其正在处理的图像的方向或其他“元数据”。我还阅读了有关使用ImageReader提取元数据的信息。根据文档,使用ImageReader.readall()应该将元数据包含在返回的IIOImage中,但是我仍然最终将某些图像颠倒了。下面的代码演示了如何在不添加水印的情况下进行复制。
File out = new File("watermarked/" + folderName + "/" + file.getName());
out.getParentFile().mkdirs();
ImageInputStream input = ImageIO.createImageInputStream(file);
ImageOutputStream output = ImageIO.createImageOutputStream(out);
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
ImageReader reader = readers.next();
reader.setInput(input);
IIOImage image = reader.readAll(0, null);
// Should not be needed since readAll should already take care of it.
IIOMetadata metadata = reader.getImageMetadata(0);
image.setMetadata(metadata);
ImageWriter writer = ImageIO.getImageWriter(reader);
writer.setOutput(output);
writer.write(image);
System.out.println(writer.canReplaceImageMetadata(0)); // Returns false
writer.replaceImageMetadata(0, metadata); // Results in a "Unsupported write variant" error.
这两个代码段都位于通过字符串folderName
和实际图像file
传递的方法中。
修改
以上代码段有效,问题出在其他方面。在我的Windows文件夹中,以Galaxy S8
制成的所有图像都以正确的方向显示。但是,当我将它们复制到项目中并在IntelliJ IDEA
中打开它们时,有些对象的方向有所不同。因此,我添加了sanselan作为依赖项,以便对图像的元数据有更多的了解,而在IDE中具有不同方向的图像的确在元数据中确实显示了不同的方向。但是为什么它们不像在Windows文件夹中那样定向,我是否缺少元数据字段或Windows在图像元数据之外的某个地方存储其他数据?