提问人:BullyWiiPlaza 提问时间:6/9/2023 最后编辑:BullyWiiPlaza 更新时间:6/10/2023 访问量:107
当 OpenCV cv::imwrite() 失败时如何获取错误详细信息
How to get error details when OpenCV cv::imwrite() fails
问:
我正在使用 cv::imwrite
使用 OpenCV 库在 C++ 中将图像写入磁盘。不幸的是,该方法只返回,所以我一直想知道如何获取实际的错误详细信息。该函数可能由于各种原因而失败,例如图像损坏、磁盘空间不足或文件路径错误。有什么方法可以获得准确的异常或错误消息吗?我的软件的某个 Windows 11 用户出现映像写入失败(返回),而相同的代码适用于许多其他用户,因此我想尽可能多地了解为什么该调用无法更轻松地缓解问题。bool
cv::imwrite
false
- 失败时不调用
cv::redirectError
回调cv::imwrite
cv::strerror
不存在
答:
1赞
BullyWiiPlaza
6/10/2023
#1
正如注释所暗示的那样,我们可以通过使用该函数并验证文件路径的有效性来手动检查错误,以提供更好的错误反馈:cv::imencode
bool is_file_path_writable(const std::filesystem::path& file_path)
{
const auto status = std::filesystem::status(file_path);
const auto permissions = status.permissions();
// Check if the file or directory is writable
return (permissions & std::filesystem::perms::owner_write) != std::filesystem::perms::none ||
(permissions & std::filesystem::perms::group_write) != std::filesystem::perms::none ||
(permissions & std::filesystem::perms::others_write) != std::filesystem::perms::none;
}
void write_string_to_file(const std::filesystem::path& file_path, const std::string& file_contents)
{
std::ofstream file_writer;
file_writer.exceptions(std::ifstream::failbit | std::ifstream::badbit);
file_writer.open(file_path.wstring(), std::ios::out | std::ios::binary);
file_writer << file_contents;
}
void error_aware_imwrite(const std::filesystem::path& output_file_path, const cv::Mat& mat)
{
if (const auto parent_path = output_file_path.parent_path();
!is_directory(parent_path))
{
throw std::runtime_error("Parent directory did not exist: " + parent_path.string());
}
if (is_regular_file(output_file_path) && !is_file_path_writable(output_file_path))
{
throw std::runtime_error("File path is not writable");
}
const auto file_extension = output_file_path.extension().string();
std::vector<uchar> buffer;
#define MB ((size_t)1024*1024)
buffer.resize(10 * MB);
if (const auto successfully_encoded = imencode(file_extension, mat, buffer);
!successfully_encoded)
{
throw std::runtime_error("Imagine encoding failed");
}
// Write to the file
const auto written_file_contents = std::string(buffer.begin(), buffer.end());
if (written_file_contents.empty())
{
throw std::runtime_error("Written image bytes were empty");
}
write_string_to_file(output_file_path, written_file_contents);
}
请注意,检查并不是绝对必要的,但它使代码“看起来”更干净(例如,如果我们不检查不存在的文件的文件权限,这实际上不会引发异常)。is_regular_file
评论
imwrite
_wfopen