#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
тоже должен работать, если позже вы столкнетесь с той же проблемой с цветными изображениями.