Windows环境下C++读取CR2文件相机型号的实现方法问询
在Windows下获取CR2图片的相机型号等详细信息
这应该不是重复提问,我没找到类似内容。想了解如何在Windows系统中获取指定CR2格式图片的详细信息,找到一段使用
GetFileAttributesEx的代码,但不确定其用法及是否为最优方案。请问能否通过文件属性获取相机型号这类自定义信息?还是需要其他方法?本人是C++新手,恳请帮助。代码如下:
std::string ImageProcessor::GetCameraType(std::string filePath) { WIN32_FILE_ATTRIBUTE_DATA fInfo; auto stemp = std::wstring(filePath.begin(), filePath.end()); GetFileAttributesEx(stemp.c_str(), GetFileExInfoStandard, &fInfo); //PrintFileAttributes(fInfo.dwFileAttributes); }
核心结论
GetFileAttributesEx完全无法获取相机型号这类信息——它只能读取文件的系统基础属性(比如文件大小、创建时间、只读/隐藏标记等),根本碰不到CR2文件内部存储的EXIF元数据,而相机型号就存放在这些元数据里。
可行实现方案
针对C++新手,推荐两种简单可靠的路径:
1. 使用Windows原生WIC接口
WIC(Windows Imaging Component)是系统自带的图像处理组件,无需额外安装库,就能直接读取CR2这类RAW格式的元数据:
#include <windows.h> #include <wincodec.h> #include <string> #include <iostream> // 编译时需链接 windowscodecs.lib std::wstring GetCameraModelFromCR2(const std::wstring& filePath) { IWICImagingFactory* pFactory = nullptr; IWICBitmapDecoder* pDecoder = nullptr; IWICMetadataQueryReader* pQueryReader = nullptr; PROPVARIANT propVar; PropVariantInit(&propVar); std::wstring cameraModel; // 初始化COM环境与WIC工厂 if (SUCCEEDED(CoInitialize(nullptr)) && SUCCEEDED(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory)))) { // 创建CR2格式解码器 if (SUCCEEDED(pFactory->CreateDecoderFromFilename( filePath.c_str(), nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder))) { // 获取元数据读取器 if (SUCCEEDED(pDecoder->GetMetadataQueryReader(&pQueryReader))) { // 查询相机型号对应的EXIF标签(路径为固定格式,272是相机型号的标签ID) if (SUCCEEDED(pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=272}", &propVar)) && propVar.vt == VT_LPWSTR) { cameraModel = propVar.pwszVal; } } } } // 释放资源 PropVariantClear(&propVar); if (pQueryReader) pQueryReader->Release(); if (pDecoder) pDecoder->Release(); if (pFactory) pFactory->Release(); CoUninitialize(); return cameraModel; } // 调用示例 int main() { std::wstring filePath = L"C:\\test\\sample.cr2"; std::wstring model = GetCameraModelFromCR2(filePath); std::wcout << L"相机型号:" << model << std::endl; return 0; }
- 注意:如果需要其他EXIF信息(比如快门速度、光圈),可以查EXIF标签ID对照表,替换路径中的
{ushort=272}部分。
2. 使用第三方轻量库(libexif)
如果觉得WIC的COM接口太繁琐,可以用专门处理EXIF的开源库libexif,API更直观,代码更简洁:
#include <libexif/exif-data.h> #include <string> std::string GetCameraModelFromCR2(const std::string& filePath) { ExifData* ed = exif_data_new_from_file(filePath.c_str()); if (!ed) return ""; std::string cameraModel; // 直接通过标签常量获取相机型号 ExifEntry* entry = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_MODEL); if (entry && entry->data) { cameraModel = exif_entry_get_value(entry); } exif_data_unref(ed); return cameraModel; }
- 优点:不用处理COM的复杂逻辑,代码量少,适合新手快速实现需求。
对你现有代码的说明
你写的GetFileAttributesEx代码只能读取WIN32_FILE_ATTRIBUTE_DATA结构体里的字段,比如dwFileAttributes是文件的系统属性标记(只读、隐藏等),nFileSizeHigh/nFileSizeLow是文件大小,这些字段和图片的元数据没有任何关联,所以完全无法用来获取相机型号。
内容的提问来源于stack exchange,提问作者maxim bouckaert
相关产品推荐
相关产品推荐

