【发布时间】:2017-11-10 02:53:03
【问题描述】:
我正在开发一个缩略图创建器作为外壳扩展。
为此,我选择实现接口IExtractImage。
我的 dll 已加载并正确调用,但缩略图始终为黑色,而不是红色。
我错过了什么?
class MyShellPreview : public IExtractImage, IPersistFile
// set by IExtractImage::GetLocation
SIZE m_size;
IFACEMETHODIMP Extract(HBITMAP *phBmpImage)
{
size_t size = m_size.cx * m_size.cy * 3;
// alloc buffer
BYTE *buffer = (BYTE*)malloc(size);
// fill buffer
for (k = i = 0; i < m_size.cx; ++i)
{
for (j = 0; j < m_size.cy; ++j, ++k)
{
buffer[k] = 128;
buffer[k+1] = 0;
buffer[k+2] = 0;
}
}
*phBmpImage = CreateBitmap(m_size.cx, m_size.cy, 3, 8, buffer);
free(buffer);
return S_OK;
}
};
我知道出于性能原因,我应该使用CreateCompatibleBitmap 和SetDIBits,但我不确定应该从哪里获得HDC。
【问题讨论】:
-
你确实没有有3个颜色平面,所以
CreateBitmap的第二个参数应该是1。除此之外,我强烈建议创建32-bpp位图,因为那是所有现代图形硬件在内部使用的东西。它将节省进行转换的需要,并使您的生活更简单。请记住,在 Windows 中,因为它是 little-endian,所以使用 BGRA 格式。 -
谢谢。我从
CreateBitmap(m_size.cx, m_size.cy, 1, 8, buffer)开始没有成功,我只是尝试CreateBitmap(m_size.cx, m_size.cy, 1, 32, buffer),它似乎好多了...... -
对。您正在填充它,就好像它是一个 32-bpp 图像一样。 8-bpp 是一种indexed 格式,您还没有设置调色板。所有关于颜色格式的信息都记录在 MSDN 和其他地方,但它很复杂,如果您像现在其他人一样只使用 32-bpp 格式,则无需担心。
-
由于您使用的是 24bpp 缓冲区,您需要为 cBitsPerPel 传递 24。并且您需要在缓冲区中对扫描线进行 DWORD 对齐。或者直接使用 32bpp 数据(自动正确对齐)。
-
你也永远不会改变
k,所以你不会填充或操作除了第一个像素之外的任何东西,不管上面的cmets说什么!您需要同时解决所有这些问题才能使其正常工作。