使用 R 中的 jpeg 包检测无效或损坏的 jpg 文件

Detecting invalid or corrupt jpg files with jpeg package in R

我想使用 jpeg 包(或类似包)来检测损坏的 .jpg 文件。我正在与安装时遇到问题的用户共享此代码 exiftool,因此我更愿意使用不需要该程序的软件包。

我希望我的代码能够捕获完全损坏或部分损坏的图像(即,您可以看到部分图像,但其中一些被截断了)。

当图像损坏时,readJPEG 函数 returns:

Error in readJPEG(photos[35]) : 
  JPEG decompression error: Not a JPEG file: starts with 0x7b 0x28

当图像部分损坏时,函数 returns:

JPEG decompression: Corrupt JPEG data: premature end of data segment

我想编写一个函数,如果图像 "good" 为 return FALSE,如果损坏或部分损坏则为 TRUE。到目前为止,如果图​​像部分损坏(returns FALSE),我将无法使用我的函数。我做错了什么?

Here's an example of a "partially corrupt" image - 下半部分在转移到新设备时被切断了。

library(jpeg)

    # Function to "catch" bad photos
is_corrupted <- function(x){
  tryCatch({
    check <- readJPEG(x)
    return(FALSE)
    },
    error = function(e)
      return(TRUE),
    warning = function(w)
      return(TRUE),
    message = function(m)
      return(TRUE)
    )
}

编辑: 尝试数字 2...

我根据 Ben 的建议创建了一个修改后的函数,但如果图像完全损坏,它仍然无法 returning TRUE。我也不喜欢它对照片进行两次测试的方式。任何建议表示赞赏!

要测试该功能,您可以使用三个 jpg...(1) 您计算机中的任何有效 jpg,(2) 此问题中链接的 "partially corrupt" 文件,以及 (3) 引用一个文件不存在抛出将被 tryCatch 捕获的错误(例如 is_corrupted("").

is_corrupted <- function(x){
message <- capture.output(check2 <- readJPEG(x), type = "message")
if(length(message) > 0) {
  corrupt <- TRUE
} else {
corrupt <- tryCatch({
    check <- readJPEG(x)
    return(FALSE)
  },
  error = function(e) # catch "corrupt" images
    return(TRUE)
  ) 
}
return(corrupt)
}

我同意,这很棘手。我认为您需要在捕获部分之前进行错误检查。我将 post 一个临时的(丑陋的)解决方案,希望其他人 post 是一个更优雅和直接的解决方案。

readJPEG2 <- purrr::safely(readJPEG)

purrr进行错误检查,如果有none,继续检查输出:

fun <- function(x){
          if(is.null(readJPEG2(x)$error)){
                    message2 <- capture.output(readJPEG(x), type = "message")
                    if(length(message2) > 0){
                              return("partially corrupted")
                    } else {
                              return("complete")
                    }
          } else {
                    return("corrupted")
          }

}

我不知道这个解决方案有多稳健,但也许它对你有帮助。