Copiar imagem com canal alfa para área de transferência com cor de fundo personalizada?

Código:

private void Foo(Canvas canvas)
{
    // The content is a bit larger...
    Size size = new Size(canvas.ActualWidth * 1.1, canvas.ActualHeight * 1.2);

    // Create a render bitmap and push the surface to it
    RenderTargetBitmap renderBitmap =
        new RenderTargetBitmap(
        (int)size.Width,
        (int)size.Height,
        96d,
        96d,
        PixelFormats.Pbgra32
    );
    renderBitmap.Render(canvas);

    // Then copy to clipboard
    Clipboard.SetImage(renderBitmap);
}

O que eu preciso :

Renderize uma tela com fundo transparente para a imagem e copie-a para a área de transferência (Sair simples? Não realmente)

Problema:

Quando colar, fico com uma imagem feia com fundo preto

Solução 1:

canvas.Background = new SolidColorBrush(Colors.White);

Não. Esta espessura não funciona, o fundo decanvas não vai mudar na próximarenderBitmap.Render(canvas);

Em vez disso, tenho que usar um timer, dar ao WPF algum tempo para alterar o plano de fundo e, em seguida, renderizá-lo no evento tick desse timer. Funciona, mas infelizmente, o conteúdo decanvas é maior do que o tamanho ... então o fundo branco só pode cobrir parte dele, resultado ainda feio. (BTW alguém sabe por que leva algum tempo para mudar o fundo? Eu pensei que deveria ser mudado instantaneamente)

Fiz algo de errado? Como posso obter uma imagem transparente de fundo branco na área de transferência?

Além do mais, tenho notado que o fundo de algumas imagens PNG permanecem em branco se você colá-lo em mspaint.exe, que não suportam canal alfa, mas alguns outros ficam pretos.

Existe algo como, digamos,alternative color, que é usado como plano de fundo se o local em que você cola sua imagem não é compatível com o canal alfa? Podemos personalizar isso?

Agora eu fiz outraBitmapSource com conteúdo branco, se houver uma maneira de combiná-lo com orenderBitmap como pano de fundo, o problema foi resolvido, mas não sei como ...

int dWidth = (int)size.Width;
int dHeight = (int)size.Height;
int dStride = dWidth * 4;
byte[] pixels = new byte[dHeight * dStride];
for (int i = 0; i < pixels.Length; i++)
{
    pixels[i] = 0xFF;
}
BitmapSource bg = BitmapSource.Create(
    dWidth,
    dHeight,
    96,
    96,
    PixelFormats.Pbgra32,
    null,
    pixels,
    dStride
);
// Combine bg with renderBitmap

questionAnswers(2)

yourAnswerToTheQuestion