【问题标题】:Direct2D bitmap brush elongatedDirect2D 位图画笔拉长
【发布时间】:2015-05-02 13:59:16
【问题描述】:

我必须在屏幕外的位图上绘制我的形状,但是当我尝试渲染我的位图时遇到了一个奇怪的问题。

这就是图像的显示方式:

这就是我看到位图的方式:

以下是我用来创建位图画笔的代码:

const auto size = renderTarget->GetSize();
const auto pxSize = D2D1::SizeU(size.width * 4, size.height * 4);

ID2D1BitmapRenderTarget* compatibleRenderTarget;
HRESULT hr = renderTarget->CreateCompatibleRenderTarget(size, pxSize, &compatibleRenderTarget);

if (SUCCEEDED(hr))
{
  // compute visible area and the current transformation matrix
  const auto area = get_visible_area(renderTarget);
  const auto transform = D2D1::Matrix3x2F::Identity();

  // offscreen bitmap rendering
  compatibleRenderTarget->BeginDraw();

  // draw all shapes

  compatibleRenderTarget->EndDraw();

  // Retrieve the bitmap from the render target.
  ID2D1Bitmap* bitmap;
  hr = compatibleRenderTarget->GetBitmap(&bitmap);

  // release the compatible render target
  compatibleRenderTarget->Release();

  // Create the bitmap brush
  ID2D1BitmapBrush* bitmapBrush = nullptr;
  hr = renderTarget->CreateBitmapBrush(bitmap, D2D1::BitmapBrushProperties(), &bitmapBrush);
  bitmap->Release();


  // draw bitmap
  renderTarget->FillRectangle(area, bitmapBrush);
}

【问题讨论】:

  • 您的问题是关于扩展的底线,还是关于位图质量损失的问题?
  • @AntonAngelov 这是关于扩展的底线。实际上我只是通过将兼容的渲染目标的大小加倍来修复它,但我不能说为什么......
  • 为什么不使用 ID2D1RenderTarget::DrawBitmap() 并传递离屏位图,而不是创建位图画笔?它要简单得多。还有第二个问题.. 每次在 HWND 渲染目标上渲染时,您是否重绘屏幕外位图?
  • @AntonAngelov 我会尝试 DrawBitmap 方法,是的,每次调用我的渲染方法时我都会重绘位图(也就是说,每次我需要添加一个新的“手绘”形状时,不幸的是,这种情况经常发生,因为几何是不可变的对象)。有没有办法避免重绘位图?
  • 如果每次渲染到窗口时都重新绘制屏幕外位图,那么您将失去所有使用屏幕外位图的好处。这将毫无意义。因此,您必须创建单独的函数 (1.) 绘制到屏幕外位图和 (2.) 函数在 HWND 渲染目标上绘制。并且仅在某些形状发生更改而不是每次在 HWN RT 上渲染时调用第一个函数 (1)。在 HWND RT 上绘图时,首先计算离屏位图的可见区域(仅当您已缩放时),然后使用 DrawBitmap() 将这个特定区域复制到 HWND RT 上。

标签: c++ bitmap rendering direct2d


【解决方案1】:

效果是标准行为的结果。如果您使用位图画笔,您可以选择不同的扩展模式(默认为钳位)。这定义了如果几何大小超过位图大小(如 FillRect() 的情况)会发生什么。您必须在传递给 ID2D1RenderTarget::CreateBitmapBrush()D2D1_BITMAP_BRUSH_PROPERTIES 结构中定义 X 和 Y 轴的扩展模式。

您可以在 (as stated here) 之间进行选择:

  • 钳位(重复位图的最后一行)
  • 环绕(平铺位图)
  • 镜子

如果你不希望你的位图被夹住也不被包裹,你可以使用 ID2D1RenderTarget::DrawBitmap() 方法。

编辑:如果 sourceRectangledestinationRectangle 的大小不同,位图将被拉伸。您可以通过指定D2D1_BITMAP_INTERPOLATION_MODE来调整拉伸质量(算法)。我认为它默认为最近邻,但线性插值质量更好。

【讨论】:

    猜你喜欢
    • 2015-04-17
    • 2015-04-20
    • 1970-01-01
    • 2017-09-24
    • 2016-06-11
    • 2015-05-02
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    相关资源
    最近更新 更多