c++ - ID2D1Bitmap1:: map 问题

标签 c++ directx direct2d

我有一个 ID2D1BitmapBrush。我想要实现的是获取其图像数据。这是我试过的:

// imageBrush - ID2D1BitmapBrush
// topLeft is a d2d1_point2u (0,0)
// uBounds is image bounding rectangle

Microsoft::WRL::ComPtr<ID2D1Bitmap> tmpBitmap;
Microsoft::WRL::ComPtr<ID2D1Bitmap1> tmpBitmap1;
D2D1_MAPPED_RECT bitmapData;

imageBrush->GetBitmap(tmpBitmap.ReleaseAndGetAddressOf());

///Creating a new bitmap

D2D1_SIZE_U dimensions;
dimensions.height = uBounds.bottom;
dimensions.width = uBounds.right;

D2D1_BITMAP_PROPERTIES1  d2dbp;
D2D1_PIXEL_FORMAT d2dpf;
FLOAT dpiX = 0;
FLOAT dpiY = 0;

d2dpf.format = DXGI_FORMAT_R8G8B8A8_UNORM;
d2dpf.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;

d2dFactory->GetDesktopDpi(&dpiX, &dpiY);

d2dbp.pixelFormat = d2dpf;
d2dbp.dpiX = dpiX;
d2dbp.dpiY = dpiY;
d2dbp.bitmapOptions = D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
d2dbp.colorContext = nullptr;

HRESULT hr = d2dCtx->CreateBitmap(dimensions, nullptr, 0, d2dbp, tmpBitmap1.GetAddressOf());

/// Getting image data

tmpBitmap1.Get()->CopyFromBitmap(&topLeft, tmpBitmap.Get(), &uBounds);
tmpBitmap1.Get()->Map(D2D1_MAP_OPTIONS_READ, &bitmapData);

问题是 - 最后 bitmapData.bits 是空的。

我哪里做错了?

最佳答案

从上面的代码开始,并提供适当的位图画笔后,只需要进行几处修改(保留变量名等)。

ID2D1Factory1* d2dFactory = /* [ get current factory ] */;
ASSERT(d2dFactory);

ID2D1DeviceContext* d2dCtx = /* [ get current target ] */;
ASSERT(d2dCtx);

Microsoft::WRL::ComPtr<ID2D1Bitmap> tmpBitmap { };
Microsoft::WRL::ComPtr<ID2D1Bitmap1> tmpBitmap1 { };
D2D1_MAPPED_RECT bitmapData { };

imageBrush->GetBitmap(tmpBitmap.ReleaseAndGetAddressOf());
ASSERT(tmpBitmap);

D2D1_SIZE_F const bitmapSize = tmpBitmap->GetSize();
ASSERT(bitmapSize.width > 0.0f);
ASSERT(bitmapSize.height > 0.0f);

D2D1_RECT_U const uBounds
{
    0u,
    0u,
    static_cast<UINT32>(bitmapSize.width),
    static_cast<UINT32>(bitmapSize.width)
};

D2D1_SIZE_U const dimensions
{
    uBounds.bottom,
    uBounds.right
};

D2D1_BITMAP_PROPERTIES1 d2dbp { };
D2D1_PIXEL_FORMAT d2dpf { };
FLOAT dpiX = 0.0f;
FLOAT dpiY = 0.0f;

// This modification to the color format was required 
// to correlate with my swap chain format.  Otherwise 
// you will receive an error [E_INVALIDARG ] when 
// calling CopyFromBitmap (as you had described)
d2dpf.format = DXGI_FORMAT_B8G8R8A8_UNORM; // <-- previously DXGI_FORMAT_R8G8B8A8_UNORM;
d2dpf.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
d2dbp.pixelFormat = d2dpf;

d2dFactory->GetDesktopDpi(&dpiX, &dpiY);
d2dbp.dpiX = dpiX;
d2dbp.dpiY = dpiY;

d2dbp.bitmapOptions = D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
d2dbp.colorContext = nullptr;

HRESULT hr = S_OK;
// [ omitting the interrogation of hr ]
D2D1_POINT_2U const topLeft { uBounds.left, uBounds.top };
hr = d2dCtx->CreateBitmap(dimensions, nullptr, 0u, d2dbp, tmpBitmap1.GetAddressOf());
hr = tmpBitmap1.Get()->CopyFromBitmap(&topLeft, tmpBitmap.Get(), &uBounds);
hr = tmpBitmap1.Get()->Map(D2D1_MAP_OPTIONS_READ, &bitmapData);
ASSERT(bitmapData.pitch == /* [call funtion to determine pitch] */);
ASSERT(bitmapData.bits != nullptr);
// [ ... code to further utilize bits ]

主要更改是确保像素格式与交换链中设置的格式相关,以避免在调用 CopyFromBitmap< 时出现您描述的错误(E_INVALIDARG 一个或多个参数无效)/强>。

附加代码用于验证生成的 D2D1_MAPPED_RECT(间距和位)。希望这会有所帮助。

关于c++ - ID2D1Bitmap1:: map 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35942868/

相关文章:

c++ - 一个棘手的计数器 - 只是一个整数,但他不会按要求工作

c++ - 为多个类或函数声明一次模板<typename T>

c++ - 在 C++ 中使用 Direct X 9 从 X 文件加载网格

direct2d - Direct2D 是否使用后台缓冲区?

c++ - 在不单独绘制每个 channel 的情况下移动颜色 channel ?

c++ - 如何防止direct2d “stretching”窗口大小改变时的 View ?

c++ - COM 对象的 SAFEARRAY

c++ - VS 2012 模板错误

c++ - 捕获 NTSC 模拟板时 DirectShow 像素乱序

graphics - Direct3D:设备->SetStreamSource 中的流编号有何作用?