C++ ID2D1Bitmap1::映射问题

C++ ID2D1Bitmap1::映射问题,c++,directx,direct2d,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> tm

我有一个
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);
//imageBrush-ID2D1BitmapBrush
//左上角是d2d1_点2u(0,0)
//uBounds是图像边框
微软::WRL::ComPtr tmpBitmap;
微软::WRL::ComPtr tmpBitmap1;
D2D1_-MAPPED_-RECT位图数据;
imageBrush->GetBitmap(tmpBitmap.ReleaseAndGetAddressOf());
///创建新位图
D2D1_尺寸_尺寸;
尺寸.高度=uBounds.底部;
尺寸.宽度=uBounds.右侧;
D2D1_位图_属性1 d2dbp;
D2D1_像素_格式d2dpf;
浮点数dpiX=0;
浮点dpiY=0;
d2dpf.format=DXGI_格式_r8g8ba8_UNORM;
d2dpf.alphaMode=D2D1α模式预乘;
d2dFactory->GetDesktopDpi(&dpiX和&dpiY);
d2dbp.pixelFormat=d2dpf;
d2dbp.dpiX=dpiX;
d2dbp.dpiY=dpiY;
d2dbp.bitmapOptions=D2D1_位图_选项_CPU_读取| D2D1_位图_选项_无法_绘制;
d2dbp.colorContext=nullptr;
HRESULT hr=d2dCtx->CreateBitmap(维度,nullptr,0,d2dbp,tmpBitmap1.GetAddressOf());
///获取图像数据
tmpBitmap1.Get()->CopyFromBitmap(&topLeft,tmpBitmap.Get(),&uBounds);
tmpBitmap1.Get()->Map(D2D1\u Map\u选项\u读取和位图数据);
问题是-在结尾
位映射数据。位
为空


我哪里弄错了?

从上面的代码开始,并提供了一个合适的位图画笔,只需要进行一些修改(保留变量名等)

ID2D1Factory1*d2dFactory=/*[获取当前工厂]*/;
断言(d2dFactory);
ID2D1DeviceContext*d2dCtx=/*[获取当前目标]*/;
断言(d2dCtx);
微软::WRL::ComPtr tmpBitmap{};
微软::WRL::ComPtr tmpBitmap1{};
D2D1_-MAPPED_-RECT位图数据{};
imageBrush->GetBitmap(tmpBitmap.ReleaseAndGetAddressOf());
断言(tmpBitmap);
D2D1_SIZE_F const bitmapSize=tmpBitmap->GetSize();
断言(bitmapSize.width>0.0f);
断言(bitmapSize.height>0.0f);
D2D1直接构造边界
{
0u,
0u,
静态_转换(位图大小.宽度),
静态_转换(bitmapSize.width)
};
D2D1尺寸常数尺寸
{
uBounds.bottom,
对
};
D2D1_位图_属性1 d2dbp{};
D2D1_像素_格式d2dpf{};
浮动dpiX=0.0f;
浮动dpiY=0.0f;
//需要对颜色格式进行此修改
//与我的交换链格式关联。否则
//您将在以下情况下收到错误[E_INVALIDARG]
//调用CopyFromBitmap(如您所述)
d2dpf.format=DXGI_format_B8G8R8A8_UNORM;//GetDesktopDpi(&dpiX和&dpiY);
d2dbp.dpiX=dpiX;
d2dbp.dpiY=dpiY;
d2dbp.bitmapOptions=D2D1_位图_选项_CPU_读取| D2D1_位图_选项_无法_绘制;
d2dbp.colorContext=nullptr;
HRESULT hr=S_正常;
//[省略对hr的询问]
D2D1_点_2U常数左上{uBounds.left,uBounds.top};
hr=d2dCtx->CreateBitmap(维度,nullptr,0u,d2dbp,tmpBitmap1.GetAddressOf());
hr=tmpBitmap1.Get()->CopyFromBitmap(&topLeft,tmpBitmap.Get(),&uBounds);
hr=tmpBitmap1.Get()->Map(D2D1\u Map\u OPTIONS\u READ,&bitmapData);
断言(bitmapData.pitch==/*[调用函数以确定基音]*/);
断言(bitmapData.bits!=nullptr);
//[…进一步利用位的代码]
主要更改是确保像素格式与交换链中设置的格式相关联,以避免在调用CopyFromBitmap时出现您描述的错误(
E\u INVALIDARG一个或多个参数无效)


额外的代码用于验证生成的D2D1映射矩形(基音和比特)。希望这能有所帮助。

您并不是在使用
successed
FAILED
检查HRESULT值的成功或失败,也不是在检查返回的每个HRESULT(即
CopyFromBitmap
返回您忽略的HRESULT)。您可能在缺少的
映射之前有一个错误代码。@ChuckWalbourn您是对的。它说-E_INVALIDARG一个或多个参数无效。这可能是因为我试图将id2d1bitmap复制到id2d1bitmap1吗?解决了这个问题。仍然没有得到正确的D2D1映射。。
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 ]