Как разрешить «java.io.EOFException: неожиданный конец входного потока ZLIB» при использовании ImageIO.read()

файл png

Я могу открыть png, но использовать код для его чтения не удалось. Исключением является «java.io.EOFException: неожиданный конец входного потока ZLIB», а строка 4, где используется функция ImageIO.read().

Мне удалось прочитать другие PNG, используя тот же код.

public static void cut(String srcImageFile, String result, int x, int y, int width, int height) {
    try {
        // 读取源图像
        BufferedImage bi = ImageIO.read(new File(srcImageFile));
        int srcWidth = bi.getHeight(); // 源图宽度
        int srcHeight = bi.getWidth(); // 源图高度
        if (srcWidth > 0 && srcHeight > 0) {
            Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
            // 四个参数分别为图像起点坐标和宽高
            // 即: CropImageFilter(int x,int y,int width,int height)
            ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
            Image img = Toolkit.getDefaultToolkit()
                    .createImage(new FilteredImageSource(image.getSource(), cropFilter));
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
            g.dispose();
            // 输出为文件
            ImageIO.write(tag, "PNG", new File(result));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Подскажите пожалуйста как решить проблему.


person user10125164    schedule 10.07.2019    source источник
comment
Похоже, изображение повреждено или имеет допустимый формат для ImageIO   -  person MadProgrammer    schedule 10.07.2019
comment
Изображение могло быть повреждено. Откройте изображение в каком-нибудь редакторе, сохраните его обратно и повторите попытку.   -  person Kris    schedule 10.07.2019
comment
Я могу открыть png Вы имеете в виду, что можете просмотреть изображение, если откроете его в чем-то вроде Paint в Windows?   -  person Abra    schedule 10.07.2019
comment
Мне удалось прочитать другие png, используя тот же код. Это означает, что только одно изображение не может быть открыто? Может быть, неправильный размер или файл был поврежден? Попробуйте посмотреть здесь   -  person Dred    schedule 10.07.2019
comment
Спасибо за вашу помощь! Я узнал несколько подобных вопросов, но не решил свою проблему. PNG сохраняется на сервере и имеет URL-адрес. Я могу просмотреть его в браузере, таком как хром, IE, fire fox.... Я использовал UrlConnection для получения потока ввода, затем использовал «чтение», но не удалось. Я сохранил его из хрома, а затем использовал код для чтения.   -  person user10125164    schedule 10.07.2019
comment
Итак, есть ли какой-нибудь метод, который мы можем использовать для чтения поврежденного png?   -  person user10125164    schedule 10.07.2019
comment
Я загрузил png на некоторые веб-сайты, на которых есть функция вырезания img, я попробовал и преуспел. Это привело меня в замешательство.   -  person user10125164    schedule 10.07.2019


Ответы (1)


Если вы откроете изображение в Chrome или другом инструменте, вы увидите, что нижняя часть изображения (часть QR-кода) отсутствует или просто черная. Это связано с тем, что файл PNG действительно поврежден или, скорее, усечен. Нет никакого способа «решить» это, кроме как получить новую копию файла без усечения.

Однако можно частично прочитать файл PNG с помощью Java, как и в других инструментах. Это просто невозможно сделать с помощью ImageIO.read(...) удобных методов, потому что вы получите исключение и не вернете никакого значения.

Вместо этого используйте полный подробный код:

BufferedImage image;

try (ImageInputStream input = ImageIO.createImageInputStream(file)) {
    ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle no reader case

    try {
        reader.setInput(input);

        int width = reader.getWidth(0);
        int height = reader.getHeight(0);

        // Allocate an image to be used as destination
        ImageTypeSpecifier imageType = reader.getImageTypes(0).next();
        image = imageType.createBufferedImage(width, height);

        ImageReadParam param = reader.getDefaultReadParam();
        param.setDestination(image);

        try {
            reader.read(0, param); // Read as much as possible into image
        }
        catch (IOException e) {
            e.printStackTrace(); // TODO: Handle
        }
    }
    finally {
        reader.dispose();
    }
}

// image should now contain the parts of the image that could be read
person Harald K    schedule 05.08.2019