【问题标题】:Detecting invalid or corrupt jpg files with jpeg package in R在 R 中使用 jpeg 包检测无效或损坏的 jpg 文件
【发布时间】:2019-08-27 00:21:12
【问题描述】:

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

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

当图像损坏时,readJPEG 函数返回:

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

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

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

我想编写一个函数,如果图像“好”则返回 FALSE,如果图像损坏或部分损坏则返回 TRUE。到目前为止,如果图​​像部分损坏(它返回 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)
    )
}

编辑:尝试第二个...

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

要测试该功能,您可以使用三个 jpg...(1) 计算机中的任何有效 jpg,(2) 此问题中链接的“部分损坏”文件,以及 (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)
}

【问题讨论】:

  • 部分损坏文件的返回行看起来像 message 而不是 warning。您可以尝试在is_corrupted 中将“警告”替换为“消息”。
  • 谢谢@BenNutzer!我确实尝试过 - 没有骰子,但感谢您的建议 :( 我将编辑该功能,以便人们知道这也不起作用。
  • 我使用purrr::quietly(readJPEG) 测试了您的方法,并且包装的函数没有返回消息或警告。我不知情的猜测是它与底层 .Call 到另一个函数有关。一种解决方法是使用capture.out(readJPEG(x), type = "message") 并评估输出。我的底线是:您的代码很好,只是不起作用。也许其他人可以证实/反驳这一点。
  • 我又试了一次,但我无法让它工作,我想我错过了一些非常简单的东西。你会看看吗?

标签: r try-catch jpeg corrupt


【解决方案1】:

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

readJPEG2 <- purrr::safely(readJPEG)

purrr 做错误检查,如果没有,继续检查输出:

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")
          }

}

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

【讨论】:

  • 丑陋与否,它绝对有效(谢谢!!!!)。 :P 你知道如何阻止它写入消息“JPEG 解压缩:损坏的 JPEG 数据:数据段的过早结束”(如“安静 = TRUE”选项)?
  • 很高兴您发现它有帮助!我也试图压制消息但失败了(suppressMessages)。我认为这与阻止您的代码正常工作的问题相同。
  • 我向 Simon 的 gitHub 页面添加了一个问题(jpeg 的作者)。如果有任何变化,我会在这里更新。
猜你喜欢
  • 2010-09-16
  • 2018-03-29
  • 2019-12-31
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2020-03-21
相关资源
最近更新 更多