从IWICBitmapSource,IWICBitmap,IWICBitmapDecoder获取位图BitsPerPixel,无论在哪里

时间:2014-09-11 21:51:34

标签: bitmap direct2d directdraw

我认为这个主题说明了一切。但是在某些细节上,我正在加载,操作,然后显示位图,并在GDI中进行。现在我想增加一些速度,因为它反复发生。

许多年前,我使用DirectX进行其他操作,但我所见过的所有东西都说是脱离DirectX,去Direct2D。所以,时间扔掉所有的知识,重新开始。真正的MS方式; - )

好吧,为了操作位图,在进入渲染之前,我看到我可以使用' Lock()'来获取它。并且界面上的功能也会告诉我大小。但我也需要知道BBP,并且迈出了步伐。

在有人说'#34;为什么不使用:: GetBBP()... DUH",经过数小时的搜索后,我还没能找到类似的东西MSDN和其他来源。那里有很多令人困惑的COM接口。

我唯一能找到的是GetPixelFormat(),它返回一个GUID,然后我写了大约150" if(...)"用来比较它的陈述。正因如此,我可以测试它的三个值和一个拒绝,如果它们都没有(1,8,32)几乎没有一个有效的方法来解决这个问题。

GetPixelFormat()并没有告诉我这个步伐。

有办法做到这一点吗?

(位图也是未压缩的,所以我甚至不需要通过IWICBitmapDecoder运行它们,但我还没有解开如何简单地告诉IWICBitmap"这里是一个blob,去使用它作为大小为x-y")的位图

感谢您的帮助。

-Scott

2 个答案:

答案 0 :(得分:3)

使用IWICPixelFormatInfo

您可以使用IWICImagingFactory.CreateComponentInfo()方法获取此界面。

  • 传递WICPixelFormatGUID的{​​{1}}值。
  • 在上面的工厂方法返回的IWICBitmap.GetPixelFormat()接口指针上使用QueryInterface( __uuidof(IWICPixelFormatInfo))来获取IWICComponentInfo接口指针。
  • 然后您可以询问IWICPixelFormatInfo指针IWICPixelFormatInfo

将其转换为每像素的字节数,然后就完成了。

比获取读锁更复杂,但仍然是另一种选择。

伪代码

GetBitsPerPixel()

答案 1 :(得分:3)

上面的答案是正确的方法,绝对不需要创建50行if语句。我必须承认这是我首先要做的,但是如果您获得了一种新格式,该怎么办?您将没有答案。这样做总是可以的。

感谢将答案发布在上面的人,但是伪代码错误地计算了步幅。跨度实质上是对所有位进行编码所需的字节数。因此,如果剩余的位少于8位,则需要再获得1个字节来管理它们。

以下是C ++的答案,主要是从WIC文档复制而来。该文档非常出色,但是如前所述,没有如何获取IWICPixelFormatInfo实例的示例。那是我无法获得的部分。

获取BitsPerPixel和步幅:

首先:获取IWICBitmapFrameDecode作为位图源

// Initialize COM.
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

IWICImagingFactory *piFactory = NULL;
IWICBitmapDecoder *piDecoder = NULL;
IWICBitmapFrameDecode *pIDecoderFrame  = NULL;
GUID *pPixelFormat = NULL; 

// Create the COM imaging factory.
if (SUCCEEDED(hr))
{
    hr = CoCreateInstance(CLSID_WICImagingFactory,
    NULL, CLSCTX_INPROC_SERVER,
    IID_PPV_ARGS(&piFactory));
}

// Create the decoder.
if (SUCCEEDED(hr))
{
    hr = piFactory->CreateDecoderFromFilename(L"test.tif", NULL, GENERIC_READ,
        WICDecodeMetadataCacheOnDemand, //For JPEG lossless decoding/encoding.
        &piDecoder);
}

// Retrieve the First frame from the image (tif might have more than 1)
if (SUCCEEDED(hr))
{
   hr = pIDecoder->GetFrame(0, &pIDecoderFrame);
}

接下来获取像素格式和BitsPerPixel

//////////////////////////////////////////////////////////////////////////////////
//// IMPORTANT PART OF THE ANSWER
//////////////////////////////////////////////////////////////////////////////////

// Get the Pixel Format
IDecoderFrame.GetPixelFormat(&pPixelFormat);

// Now get a POINTER to an instance of the Pixel Format    
IWICComponentInfo *pIComponentInfo = NULL;
if (SUCCEEDED(hr))
{
    hr = piFactory->CreateComponentInfo(pPixelFormat, &pIComponentInfo);
}

// Assign the PixelFormatPointer to pointer returned from ComponentInfo
IWICPixelFormatInfo *pIPixelFormatInfo = pIComponentInfo;

// Now get the Bits Per Pixel
UInt32 bitsPerPixel;
if (SUCCEEDED(hr))
{
   hr = pIPixelFormatInfo.GetBitsPerPixel(&bitsPerPixel);
}

您有两种选择:

//Manually Calculate the Stride from the Bits Per Pixel.
UINT width;
UINT height;
if (SUCCEEDED(hr))
{
   hr = IDecoderFrame.GetSize(&width, &height);
}
float totalPixels = bitsPerPixel * width + 7; // +7 forces to next byte if needed
UINT stride = totalPixels / 8;

// ... now do something with stride-You can stop here if you dont need the bitmap

//////////////////////////////////////////////////////////////////////////////////

或者,如果您想使用图像,可以创建它...

// Alternative is to get a lock, by you need to actually create the bitmap
// by calling CreateBitmapFromSource.  IF you do want to create the bitmap,
// then by all means create one.  


IWICBitmap *pIBitmap = NULL;
IWICBitmapLock *pILock = NULL;


WICRect rcLock = { 0, 0, width, height }; // from GetSize earlier

// Create the bitmap from the image frame.
if (SUCCEEDED(hr))
{
   hr = m_pIWICFactory->CreateBitmapFromSource(
      pIDecoderFrame,          // Create a bitmap from the image frame
      WICBitmapCacheOnDemand,  // Cache metadata when needed
      &pIBitmap);              // Pointer to the bitmap
}

if (SUCCEEDED(hr))
{
   hr = pIBitmap->Lock(&rcLock, WICBitmapLockWrite, &pILock);   
}

// Now get the stride from the lock.
piLock.GetStride(&stride);

/// END OF ANSWER
/////////////////////////////////////////////////////////////////////////////////

别忘了整理...

SafeRelease(&pILock);
...