问题
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