ImageIO.write(img, «jpg», pathtosave) JAVA не сохраняет файл изображения в выбранный путь к файлу

#java #visual-studio-code #vscode-settings #javax.imageio #grayscale

#java #visual-studio-code #javax.imageio #оттенки серого

Вопрос:

Я использую JVM 14.0.2 в среде разработки VSCode. Цель кода — изменить исходное входное изображение на изображение в оттенках серого и сохранить новое серое изображение в нужном месте.

Код выполняется без исключений, и я попытался напечатать несколько строк выполнения (System.out.println(«Сохранение завершено …»);), эти строки печатаются по всей программе, в которую я подключен. Однако, когда я перехожу к выбранному пути к файлу для поиска сохраненного изображения в оттенках серого, я не вижу нового изображения в каталоге.

Затем я попробовал BlueJ IDE, и серое изображение было сохранено. Можете ли вы проверить, является ли это проблемой среды разработки VSCode или проблемой моего кода? или мне нужен другой класс / метод для редактирования изображений в VSCode? Спасибо за вашу помощь.Дайте мне знать, если вам нужна дополнительная информация.

 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. Ваш код выглядит нормально (хотя, вероятно, не самый эффективный / «правильный» способ преобразования в серый). Тот факт, что он работает в другой среде IDE, также говорит о том, что это хорошо. Вероятно, вы (ваши IDE) используете разные JRE, где один из них не может хранить файлы ARGB JPEG. Я полагаю ImageIO.write(...) , что он вернется false из VSCode, но true из BlueJ. Однако вам не нужен ARGB, поэтому я думаю, что изменение grayImg на TYPE_INT_RGB или лучше TYPE_BYTE_GRAY исправит это.

Ответ №1:

Если я правильно понимаю эту проблему, важным уроком здесь является то, что ImageIO.write(...) возвращает a boolean , указывающий, удалось ли это или нет. Вы должны обрабатывать ситуации, когда значение равно false , даже если исключения нет. Для справки см. Документ API .

Что-то вроде:

 if (!ImageIO.write(grayimg, "JPEG", newf)) {
    System.err.println("Could not store image as JPEG: "   grayimg);
}
  

Теперь, по той причине, что ваш код действительно работает в одной JRE, а не в другой, вероятно, связано с тем, что изображение имеет тип TYPE_INT_ARGB (т.е. содержит альфа-канал). Раньше это работало в Oracle JDK / JREs, но поддержка была удалена:

Ранее Oracle JDK использовал собственные расширения для широко используемой библиотеки IJG JPEG для обеспечения дополнительной поддержки цветового пространства. Это использовалось для поддержки PhotoYCC и изображений с альфа-компонентом как при чтении, так и при записи. Эта необязательная поддержка была удалена в Oracle JDK 11.

Исправить это просто; поскольку ваш исходный файл является файлом JPEG, он, вероятно, в любом случае не содержит альфа-компонента, поэтому вы можете перейти на другой тип без альфа. Поскольку вам нужно серое изображение, я считаю, что наилучшим вариантом будет:

 BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
  

Но TYPE_INT_RGB или TYPE_3BYTE_BGR тоже должен работать, если позже вы столкнетесь с той же проблемой с цветными изображениями.