英文:
ImageIO.write(img,"jpg",pathtosave) JAVA not saving Image file to selected filepath
问题
public class GrayImage {
public static void main(String args[]) throws IOException {
BufferedImage img = null;
// read image
try {
File f = new File("C:\\original.jpg");
img = ImageIO.read(f);
// get image width and height
int width = img.getWidth();
int height = img.getHeight();
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// convert to grayscale
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = new Color(img.getRGB(x, y));
int r = (int) color.getRed();
int g = (int) color.getBlue();
int b = (int) color.getGreen();
// calculate average
int avg = (r + g + b) / 3;
// replace RGB value with avg
Color newColor = new Color(avg, avg, avg, color.getAlpha());
grayimg.setRGB(x, y, newColor.getRGB());
}
}
// write image
System.out.println("Trying to write the new image...");
File newf = new File("H:\\gray.jpg");
ImageIO.write(grayimg, "jpg", newf);
System.out.println("Finished writing the new image...");
} catch (IOException e) {
System.out.println(e);
}
}// main() ends here
}
英文:
I'm using JVM 14.0.2 in VSCode IDE.
The purpose of the code is to change the original input image to grayscale image and save the new gray image to the desired location.
The code runs with no exceptions and i tried to print some progress lines(System.out.println("Saving completed...");), those lines printed throughout the program where i plugged in. However, when i go to the selected filepath to search for the saved GrayScale image, i do not see the new image in the directory.
I then tried the BlueJ IDE, and the gray image was saved. Can you check if it's VSCode developing environment issue or my code issue? or I need a different class/method to edit images in VSCode? Thanks for your help.Let me know if you need more details.
public class GrayImage {
public static void main(String args[]) throws IOException {
BufferedImage img = null;
// read image
try {
File f = new File("C:\\original.jpg");
img = ImageIO.read(f);
// get image width and height
int width = img.getWidth();
int height = img.getHeight();
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// convert to grayscale
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = new Color(img.getRGB(x, y));
int r = (int) color.getRed();
int g = (int) color.getBlue();
int b = (int) color.getGreen();
// calculate average
int avg = (r + g + b) / 3;
// replace RGB value with avg
Color newColor = new Color(avg, avg, avg, color.getAlpha());
grayimg.setRGB(x, y, newColor.getRGB());
}
}
// write image
System.out.println("Trying to write the new image...");
File newf = new File("H:\\gray.jpg");
ImageIO.write(grayimg, "jpg", newf);
System.out.println("Finished writing the new image...");
} catch (IOException e) {
System.out.println(e);
}
}// main() ends here
}
答案1
得分: 1
如果我正确理解这个问题,这里的重要教训是 ImageIO.write(...)
返回一个布尔值,表示是否成功。即使没有异常,您也应处理值为 false
的情况。有关详细信息,请参阅 API 文档。
类似于:
if (!ImageIO.write(grayimg, "JPEG", newf)) {
System.err.println("无法将图像存储为 JPEG:" + grayimg);
}
现在,你的代码在一个 JRE 中工作而在另一个 JRE 中不工作的原因,可能与图像的类型为 TYPE_INT_ARGB
(即包含 alpha 通道)有关。这曾在 Oracle JDK/JRE 中工作,但已经被移除:
以前,Oracle JDK 在提供可选颜色空间支持时使用了广泛使用的 IJG JPEG 库的专有扩展。
这用于支持 PhotoYCC 和在读取和写入时带有 alpha 分量的图像。这种可选的支持在 Oracle JDK 11 中已被移除。
修复很简单;由于您的源是 JPEG 文件,它可能不包含 alpha 分量,所以您可以更改为没有 alpha 的不同类型。由于您想要一个灰度图像,我认为最佳匹配是:
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
但 TYPE_INT_RGB
或 TYPE_3BYTE_BGR
也应该适用,如果以后在彩色图像中遇到相同问题的话。
英文:
If I understand this problem correctly, the important lesson here is that ImageIO.write(...)
returns a boolean
, indicating whether it succeeded or not. You should handle situations where the value is false
, even if there is no exception. For reference, see the API doc.
Something like:
if (!ImageIO.write(grayimg, "JPEG", newf)) {
System.err.println("Could not store image as JPEG: " + grayimg);
}
Now, for the reason your code does indeed work in one JRE and not in another, is probably related to the image being of type TYPE_INT_ARGB
(ie. contains alpha channel). This used to work in Oracle JDK/JREs but support was removed:
> Previously, the Oracle JDK used proprietary extensions to the widely used IJG JPEG library in providing optional color space support.
This was used to support PhotoYCC and images with an alpha component on both reading and writing. This optional support has been removed in Oracle JDK 11.
The fix is easy; as your source is a JPEG file, it probably does not contain an alpha component anyway, so you could change to a different type with no alpha. As you want a gray image, I believe the best match would be:
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
But TYPE_INT_RGB
or TYPE_3BYTE_BGR
should work too, should you later run into the same problem with color images.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论