使用 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")
}
}
我不知道这个解决方案有多稳健,但也许它对你有帮助。
我想使用 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")
}
}
我不知道这个解决方案有多稳健,但也许它对你有帮助。