You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 00:21:26