为了提高渲染性能,我需要将ID2D1Effect转换为ID2D1Bitmap。但是当我应用效果时,出现了我不明白的问题。使用的代码来自:Direct2D: Convert ID2D1Image to ID2D1Bitmap.
错误是由于某种原因图片被交换了,尽管它们渲染的位置总是相同的
我的代码是如何工作的:首先我以 ID2D1BitmapBrush 的形式获取图像并将其缓存。然后我用它填充圆角正方形。这是必要的,以便我可以更改图像的舍入级别,从而回答我的问题:我可以将 ID2D1Bitmap 或 IWICBitmapSource 的角舍入吗?。感谢@Jeaninez - MSFT 的想法
var imageBrush = ImagesExtension.CreateGetBitmapBrush(key, out var bitmapBrushSize);
//BitmapBrush
if (imageBrush is null)
{
return;
}
var bitmapImage = CreateGetImageInRect(deviceContext, imageBrush, bitmapBrushSize, key, rect, cornerRadius, 0, out var bitmapSize);
//Make rounded image
if (bitmapImage is null)
{
return;
}
获取圆形图像的 ID2D1Bitmap 的方法:
public static unsafe ID2D1Bitmap* CreateGetImageInRect(ID2D1DeviceContext6* deviceContext, ID2D1BitmapBrush* iD2D1BitmapBrush, SizeF bitmapBrushSize,
string imgKey, RectangleF rect, float cornerRadius, float offset, out SizeF imgSize)
{
var effectOffset = offset * 3 / 2; //I need it if I'm going to draw blur, default 0
ID2D1Image* oldTarget;
ID2D1Bitmap1* targetBitmap;
var properties = new BitmapProperties1(BitmapOptions.Target, new(Format.B8G8R8A8Unorm, AlphaMode.Premultiplied));
deviceContext->CreateBitmap(new((int)(rect.Width + effectOffset), (int)(rect.Height + effectOffset)), null, 0, &properties, &targetBitmap);
deviceContext->GetTarget(&oldTarget);
deviceContext->SetTarget((ID2D1Image*)targetBitmap);
deviceContext->Clear(null);
var transform = System.Numerics.Matrix3x2.CreateScale(rect.Width / bitmapBrushSize.Width, rect.Height / bitmapBrushSize.Height);
//System.Numerics.Matrix3x2.CreateTranslation(rect.X, rect.Y);
iD2D1BitmapBrush->SetTransform(&transform);
var roundedRect = new RoundedRect()
{
rect = RectF.Create(0, 0, rect.Width, rect.Height),
radiusX = cornerRadius,
radiusY = cornerRadius,
};
deviceContext->FillRoundedRectangle(&roundedRect, (ID2D1Brush*)iD2D1BitmapBrush);
var getImgSize = targetBitmap->GetSize();
deviceContext->SetTarget(oldTarget);
oldTarget->Release();
imgSize = getImgSize;
return (ID2D1Bitmap*)targetBitmap;
}
由于模糊的强度可以等于 0,所以我没有应用任何效果,代码完全正确。但是当我应用效果时,出现了我不明白的问题。
var blurImage = CreateGetImageInRect(deviceContext, imageBrush, bitmapBrushSize, key + "_blur", rect, cornerRadius, blur, out var blurSize);
//Make second rounded image and offset for blur
if (blurImage is null)
{
return;
}
//Blur img must be bigger than original "bitmapImage"
var blurOffset = blur * 3;
var finalRect = new RectangleF(
rect.X - blurOffset / 2, rect.Y - blurOffset / 2,
rect.Width + blurOffset, rect.Height + blurOffset);
//Transform for original "bitmapImage"
ID2D1Effect* affineTransformRectEffect;
RendererManager.DeviceContext->CreateEffect(D2D1Apis.CLSID_D2D12DAffineTransform, &affineTransformRectEffect);
affineTransformRectEffect->SetInput(0, (ID2D1Image*)blurImage);
var transformRect =
System.Numerics.Matrix3x2.CreateScale(rect.Width / bitmapSize.Width, rect.Width / bitmapSize.Height);
affineTransformRectEffect->SetValue((uint)AffineTransform2DProperties.TransformMatrix, &transformRect);
//Transform for blur "blurImage"
ID2D1Effect* affineTransformEffect;
RendererManager.DeviceContext->CreateEffect(D2D1Apis.CLSID_D2D12DAffineTransform, &affineTransformEffect);
affineTransformEffect->SetInput(0, (ID2D1Image*)bitmapImage);
var transform =
System.Numerics.Matrix3x2.CreateScale(finalRect.Width / blurSize.Width, finalRect.Height / blurSize.Height) *
System.Numerics.Matrix3x2.CreateTranslation(-blur / 2, -blur / 2);
affineTransformEffect->SetValue((uint)AffineTransform2DProperties.TransformMatrix, &transform);
var size = RectF.Create(0, 0, rect.Width, rect.Height);
deviceContext->DrawImage(affineTransformEffect, new Vector2(rect.X, rect.Y), &size);
Console.WriteLine((nint)affineTransformEffect);
affineTransformEffect->Release();
affineTransformRectEffect->Release();
blurImage->Release();
bitmapImage->Release();
结果是(deviceContext->DrawImage),我得到不断变化的图片。我究竟做错了什么?效果或 GetTarget SetTarget 会不会有问题?