Pergunta

atualmente estou experimentando usando PixelShaders introduzido com .net 3.5 sp1 para melhorar o desempenho de processamento de imagem.tudo é muito mais rápido , mas o til, mas eu apenas tive a aplicação de efeitos de alguns elementos no meu wpf formas, que na verdade eu quero evitar.

temos um monte de processamento de imagem, funcionalidade e eu gostaria de substituir algumas outras coisas, peça a peça, com pixel shaders para ganho de desempenho.existe uma maneira de aplicar tal pixel shader para um ImageSource sem ter de apresentá-lo?

Foi útil?

Solução

Para quem ainda tem essa:Acabei de criar este artigo que mostra como fazer isso no WPF.http://www.codeproject.com/Articles/642151/Pixel-shaders-in-a-background-thread-in-WPF

O código copiado abaixo.ele é de uma classe com algumas variáveis armazenadas

  • Fonte:um ImageSource
  • DpiX, DpiY:duplos contendo Dpi de origem
  • img:WPF controle de Imagem
  • viewbox:WPF controle ViewBox
  • WPF_DPI_X, WPF_DPI_Y:const duplos com valor 96.0

1.a Imagem img é incorporado em um Viewbox (também fora da tela)

//prepare images
img = new Image();
img.Stretch = Stretch.None;
viewbox = new Viewbox();
viewbox.Stretch = Stretch.None;
viewbox.Child = img; //control to render

2.a img e viewbox são dimensionados para as proporções corretas, além de algumas funções de layout são chamados viewbox.isso fará com que as controles render com o shader aplicada.

/// <summary>
/// Loads the image and viewbox for off-screen rendering.
/// </summary>
public void LoadImage(double width, double height)
{
    img.BeginInit();
    img.Width = width;
    img.Height = height;
    img.Source = Source;
    img.EndInit();

    viewbox.Measure(new Size(img.Width, img.Height));
    viewbox.Arrange(new Rect(0, 0, img.Width, img.Height));
    viewbox.UpdateLayout();
} 

3.E para obter o conteúdo da imagem, uma "screenshot" se você vai:

void SaveUsingEncoder(BitmapEncoder encoder, Stream stream)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)(img.Width * DpiX / WPF_DPI_X), (int)(img.Height * DpiY / WPF_DPI_Y), DpiX, DpiY, PixelFormats.Pbgra32);
    bitmap.Render(viewbox);

    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);
    encoder.Save(stream);
} 

Além disso, se você deseja executar esta em uma thread separada, você precisará criar uma thread com

thread.SetApartmentState(ApartmentState.STA);

para mais informações e um projeto de demonstração, consulte o artigo.

Outras dicas

Vendo que você ainda não obteve nenhuma resposta de especialistas em C#, tentarei abordar isso da perspectiva do desenvolvedor do C ++ DirectX, esperando que, se minha resposta não for útil, pelo menos o apontará na direção certa. Eu sei pouco sobre C# e nada sobre como os pixelshaders são suportados; portanto, o acaso está completo e o que escrevo aqui não se aplica. Nesse caso, sinta -se à vontade para comentar ou votar, conforme necessário

O que geralmente é feito em C ++ / DirectX para alcançar isso é:

Preparação (feita uma vez)

  • Crie o alvo de renderização usando o CreaterRerTarget
  • Crie superfície fora da tela usando CreateOffScreenplainsurface
  • Defina a superfície do alvo de renderização usando o setrenderTarget
  • Crie quaisquer outros recursos de entrada necessários (texturas, buffers de vértices ...)

Renderização (feita várias vezes)

  • Atualize os recursos de entrada (texturas, buffers) conforme necessário
  • Renderizar
  • Copie o conteúdo do alvo de renderização na superfície off-telra via getrenderTarget
  • Bloqueie a superfície fora da tela e leia seu conteúdo na CPU
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top