画ID2D1Effect,但是图片变了,不像ID2D1Bitmap

问题描述 投票:0回答:0

为了提高渲染性能,我需要将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;
}

CreateGetImageInRect() 的最终图像:

由于模糊的强度可以等于 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 会不会有问题?

c# image direct2d
© www.soinside.com 2019 - 2024. All rights reserved.