2011-11-07 34 views
9

Tôi cần phát hiện xem tệp hình ảnh có bị hỏng trong Java hay không. Tôi chỉ làm việc với hình ảnh PNG, JPG. Điều này có thể thực hiện với Sanselan không? Hoặc nó có thể được thực hiện với ImageIO? Tôi đã thử bằng cách sử dụng ImageIO.read có vẻ như nó hoạt động. Nhưng tôi không chắc liệu nó có thể phát hiện mọi loại lỗi trong hình ảnh hay không. Tôi muốn biết thực hành tốt nhất là gì.Cách phát hiện hình ảnh bị hỏng (PNG, JPG) trong Java

+2

Tôi sẽ đề nghị cách duy nhất để phát hiện * mọi loại lỗi trong một hình ảnh (nơi "lỗi" được định nghĩa là bất kỳ sự khác biệt nào gây ra hành vi không hoàn hảo) là tiếp tục và sử dụng hình ảnh. Đó là hoàn toàn có thể cho một hình ảnh bị một tham nhũng mà dù sao kết quả trong một tập tin hợp lệ, mặc dù một với "các điểm ảnh sai". Nó có thể hữu ích để suy nghĩ rất cụ thể về những gì nó là bạn muốn phát hiện. –

+2

ImageIO có thể phát hiện PNG bị cắt ngắn với một ngoại lệ được ném, nhưng đối với JPG bị cắt ngắn, tôi không thể lấy nó để ném một ngoại lệ. –

+0

Bạn có nhận được giải pháp nào cho điều này không? –

Trả lời

1

Nếu hình ảnh không thể phân tích cú pháp tệp bị hỏng, nếu không tệp sẽ hợp lệ nhưng chứa sai pixel như Andrzej đã chỉ ra. Phát hiện có thể khá khó khăn nếu bạn không thể xác định cách bạn sẽ tìm thấy các pixel "sai".

Nếu bạn có thông tin về hình ảnh cơ sở, ví dụ: một biểu đồ hoặc thậm chí là các pixel gốc, bạn có thể thử và so sánh chúng với hình ảnh đã đọc. Tuy nhiên, lưu ý rằng do nén có thể có một số lỗi nên bạn cần thêm một số giá trị dung sai.

Lưu ý bổ sung: Sanselan sẽ không đọc ảnh JPEG để bạn phải sử dụng ImageIO tại đây.

9

Đây là giải pháp của tôi có thể xử lý việc kiểm tra GIF, JPG và PNG bị hỏng. Nó kiểm tra cắt ngắn JPEG bằng cách sử dụng dấu hiệu JPEG EOF, GIF sử dụng một chỉ số ra khỏi kiểm tra giới hạn ngoại lệ và PNG sử dụng một EOFException

public static ImageAnalysisResult analyzeImage(final Path file) 
     throws NoSuchAlgorithmException, IOException { 
    final ImageAnalysisResult result = new ImageAnalysisResult(); 

    final InputStream digestInputStream = Files.newInputStream(file); 
    try { 
     final ImageInputStream imageInputStream = ImageIO 
       .createImageInputStream(digestInputStream); 
     final Iterator<ImageReader> imageReaders = ImageIO 
       .getImageReaders(imageInputStream); 
     if (!imageReaders.hasNext()) { 
      result.setImage(false); 
      return result; 
     } 
     final ImageReader imageReader = imageReaders.next(); 
     imageReader.setInput(imageInputStream); 
     final BufferedImage image = imageReader.read(0); 
     if (image == null) { 
      return result; 
     } 
     image.flush(); 
     if (imageReader.getFormatName().equals("JPEG")) { 
      imageInputStream.seek(imageInputStream.getStreamPosition() - 2); 
      final byte[] lastTwoBytes = new byte[2]; 
      imageInputStream.read(lastTwoBytes); 
      if (lastTwoBytes[0] != (byte)0xff || lastTwoBytes[1] != (byte)0xd9) { 
       result.setTruncated(true); 
      } else { 
       result.setTruncated(false); 
      } 
     } 
     result.setImage(true); 
    } catch (final IndexOutOfBoundsException e) { 
     result.setTruncated(true); 
    } catch (final IIOException e) { 
     if (e.getCause() instanceof EOFException) { 
      result.setTruncated(true); 
     } 
    } finally { 
     digestInputStream.close(); 
    } 
    return result; 
} 

public class ImageAnalysisResult { 
    boolean image; 
    boolean truncated; 
    public void setImage(boolean image) { 
     this.image = image; 
    } 
    public void setTruncated(boolean truncated) { 
     this.truncated = truncated; 
    } 
} 
} 
+2

Không phải hai mệnh đề của kiểm tra điều kiện JPEG được kết nối với logic HOẶC thay vì AND? – mnicky

+0

Bạn có thể liên kết lớp này ImageAnalysisResult –

+0

Bạn có thể bao gồm tất cả các câu lệnh nhập khẩu trong câu trả lời của bạn, xin vui lòng –

4

Nếu hình ảnh trong định dạng JPEG, sử dụng này:

JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f)); 
decoder.produceImage(); 

nếu nó ném một ngoại lệ; điều này có nghĩa là hình ảnh bị hỏng.

cho các trường hợp khác; chỉ cần sử dụng new ImageIcon(file) để kiểm tra tính hợp lệ.

+0

Không hoạt động cho tôi (http://i.imgur.com/rE89Bpl.jpg). – mnicky

Các vấn đề liên quan