Can't render pixel shader to RenderTargetBitmap! Please help!

眉间皱痕 提交于 2019-12-07 21:43:15

问题


I wrote a very simple WPF application to test the ability to render a control that has an associated pixel shader to a RenderTargetBitmap. I then write the bitmap to file (jpeg). The control is rendered onto the bitmap, however the pixel shader effect is not applied to the control.

The code and the XAML is below:

namespace TestPixelShader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnSaveSnapshot(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.DefaultExt = "jpg";

            if ((bool)dlg.ShowDialog() == true)
            {
                String fileName = dlg.FileName;

                int Height = (int)CanvasControl.ActualHeight;
                int Width = (int)CanvasControl.ActualWidth;

                RenderTargetBitmap bmp = new RenderTargetBitmap(
                    Width, Height, 96, 96, PixelFormats.Pbgra32);
                bmp.Render(CanvasControl);

                string Extension = System.IO.Path.GetExtension(fileName).ToLower();

                BitmapEncoder encoder;
                if (Extension == ".gif")
                    encoder = new GifBitmapEncoder();
                else if (Extension == ".png")
                    encoder = new PngBitmapEncoder();
                else if (Extension == ".jpg")
                    encoder = new JpegBitmapEncoder();
                else
                    return;

                encoder.Frames.Add(BitmapFrame.Create(bmp));
                using (Stream stm = File.Create(fileName))
                {
                    encoder.Save(stm);
                }
            }
        }
    }
}

XAML:

<Window x:Class="TestPixelShader.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestPixelShader"
    Height="400"
    Width="300"
    Title="Test Pixel Shader">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Canvas Grid.Column="0" x:Name="CanvasControl" Margin="5"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch" >
            <Canvas.Effect>
                <local:TestPixelShaderEffect />
            </Canvas.Effect>
            <Canvas.Background>
                <ImageBrush ImageSource="/TestPixelShader;component/Images/DSCF0225.JPG" />
            </Canvas.Background>
        </Canvas>
        <Button x:Name="SaveSnapshotButton" Grid.Row="1" Click="OnSaveSnapshot" Height="40"
                Content="Take Snapshot" Margin="5"/>
    </Grid>
</Window>

回答1:


What Pixel Shader version are you targeting?

I tried your code and it saved the image correctly for a PS 2.0 shader. RenderTargetBitmap uses the software renderer and PS 3.0 doesn't have a software fallback so if your using a PS 3.0 shader it will be ignored.




回答2:


 public class SnapshotHelper
{
    public static BitmapSource Capture(Rect absoluteControlRect)
    {
        using (var screenBmp = new System.Drawing.Bitmap(
            (int)absoluteControlRect.Width,
            (int)absoluteControlRect.Height,
            PixelFormat.Format32bppArgb))
        {
            using (var bmpGraphics = System.Drawing.Graphics.FromImage(screenBmp))
            {
                bmpGraphics.CopyFromScreen((int)absoluteControlRect.Left, (int)absoluteControlRect.Top, 0, 0, screenBmp.Size);
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    screenBmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
        }
    }

    public static Rect GetAbsoltutePlacement(FrameworkElement visual)
    {
        Point absolutePos = visual.PointToScreen(new Point(0, 0));
        return new Rect(absolutePos.X, absolutePos.Y, visual.ActualWidth, visual.ActualHeight);
    }

}

Usage:

var rect = SnapshotHelper.GetAbsoltutePlacement(yourControl);
var image = SnapshotHelper.Capture(rect);


来源:https://stackoverflow.com/questions/3847097/cant-render-pixel-shader-to-rendertargetbitmap-please-help

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!