c++ - 如何访问 win32 缩略图的图像数据

标签 c++ image winapi buffer thumbnails

我正在尝试通过以下步骤访问 win32 缩略图的图像数据以将其与另一个库一起使用:

  1. 从 Windows 缩略图缓存中获取缩略图(一个 ISharedBitmap)
  2. 获取缩略图的HBITMAP
  3. 使用 GetDIBits 获取像素数据

缩略图检索基于https://stackoverflow.com/a/19529633/3165122

像素数据检索基于https://stackoverflow.com/a/3688682/3165122

这是我到目前为止得到的:

// error checks omitted
LPCTSTR path = TEXT("<path-to-jpg-image>");

HRESULT hr = CoInitialize(nullptr);

// Get the thumbnail
IShellItem* item = nullptr;
hr = SHCreateItemFromParsingName(path, nullptr, IID_PPV_ARGS(&item));

IThumbnailCache* cache = nullptr;
hr = CoCreateInstance(
    CLSID_LocalThumbnailCache,
    nullptr,
    CLSCTX_INPROC,
    IID_PPV_ARGS(&cache)); 

ISharedBitmap* shared_bitmap;
hr = cache->GetThumbnail(
    item,
    1024,
    WTS_EXTRACT,
    &shared_bitmap,
    nullptr,
    nullptr);

// Retrieve thumbnail HBITMAP
HBITMAP hbitmap = NULL;
hr = shared_bitmap->GetSharedBitmap(&hbitmap);

HDC dc = GetDC(NULL);
HDC dc_mem = CreateCompatibleDC(dc);

// Get required buffer size
BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
GetDIBits(dc_mem, hbitmap, 0, 0, nullptr, &bmi, DIB_RGB_COLORS); // <- this fails

WTS_ALPHATYPE alpha_type;
hr = shared_bitmap->GetFormat(&alpha_type);

bmi.bmiHeader.biBitCount = alpha_type == WTSAT_RGB ? 24 : 32;
bmi.bmiHeader.biHeight = std::abs(bmi.bmiHeader.biHeight);
bmi.bmiHeader.biCompression = BI_RGB;

// Get image data
std::vector<char> buffer(bmi.bmiHeader.biSizeImage);
GetDIBits(dc_mem, hbitmap, 0, bmi.bmiHeader.biHeight,
        &buffer[0], &bmi, DIB_RGB_COLORS);

// use buffer...

第一次调用 GetDIBits 以检索所需的缓冲区大小失败,返回值为 0。我猜我使用的是不兼容的 DC?如何获得兼容的 DC?

https://stackoverflow.com/a/14207674/3165122状态“[...] 如果你不知道你的 HBITMAP 指向什么,你就不能指望用它做任何有用的事情。”

真的没有办法吗?难道我做错了什么?有不同的方法吗?

最佳答案

根据 GetDIBits 文档: “如果 lpvBits 为 NULL 且 BITMAPINFO 的位计数成员初始化为零,则 GetDIBits 填充 BITMAPINFOHEADER 结构 [...]”

在我的例子中,位计数成员没有初始化为零。在声明修复它之后调用 ZeroMemory(&bmi, sizeof(BITMAPINFO))。 为了我的辩护:BITMAPINFO 是一个输出参数;)

非常感谢 Stuart!

关于c++ - 如何访问 win32 缩略图的图像数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20949827/

相关文章:

c++ - vector 中的错误内存分配

c++ - 使用 QItemDelegate 显示图片缩略图

android - 可点击的滚动图像

C++ WinAPI - 草率的鼠标输入

c++ - 哪个 STL 容器用于相互关联的数据?

c++ - 从 C 代码库在 C++ 中对 unsigned char * 上的 strchr 进行微创更改?

c++ - map 删除困难

java - iText 忽略图像后添加的空间

c++ - 如何停止正在阻塞的 win32 线程?

c++ - win32 应用程序不是面向对象的,为什么有这么多指针?