我正在使用SharpDx在WinRt的Image控件中渲染一些形状。如何打印呈现给打印机的内容?
private void RenderGraphics()
{
KSurfaceImageSourceManager _pKSurfaceImageSourceManager = new KSurfaceImageSourceManager();
SurfaceImageSource _pSurfaceImageSource = _pKSurfaceImageSourceManager.NewSurfaceImageSource((int)imageCtrl.Width, (int)imageCtrl.Height);
int _w = 0;
int _h = 0;
_pKSurfaceImageSourceManager.GetSurfaceImageSourceSize(_pSurfaceImageSource, out _w, out _h);
this.imageCtrl.Source = _pSurfaceImageSource;
int _retcode = _pKSurfaceImageSourceManager.ClearSurfaceImageSource(_pSurfaceImageSource, 1, 1, 1, 1);
int _hrenderTarget = 0;
int _offsetx = 0;
int _offsety = 0;
int _surfacewidth = 0;
int _surfaceheight = 0;
try
{
// initiating a Direct2D drawing session: BeginDraw2D
_hrenderTarget = _pKSurfaceImageSourceManager.BeginDraw2D(_pSurfaceImageSource, out _offsetx, out _offsety, out _surfacewidth, out _surfaceheight);
// connecting the _hrenderTarget handle returned by BeginDraw2D to a RenderTarget instance
_pRenderTarget = new RenderTarget(new IntPtr(_hrenderTarget));
// Direct2D drawing session targetting _pRenderTarget
_pRenderTarget.BeginDraw();
SharpDX.Direct2D1.SolidColorBrush _brush = null;
int _left = _offsetx;
int _top = _offsety;
int _right = _surfacewidth;
int _bottom = _surfaceheight;
// border
_brush = new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, new SharpDX.Color4(1, 0, 0, 1));
_pRenderTarget.FillRectangle(new SharpDX.RectangleF(_left, _top, _right, _bottom), _brush);
// fill
int _border = 2;
_brush = new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, new SharpDX.Color4(1, 1, 1, 1));
_pRenderTarget.FillRectangle(new SharpDX.RectangleF(_left + _border, _top + _border, _right - 2 * _border, _bottom - 2 * _border), _brush);
_pRenderTarget.DrawEllipse(new SharpDX.Direct2D1.Ellipse(new DrawingPointF(50, 80), 50, 50), new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, Color.SlateBlue));
}
catch (Exception E)
{
}
finally
{
_pKSurfaceImageSourceManager.EndDraw2D(_pSurfaceImageSource);
}
}
我试图在不执行这些渲染操作的情况下打印图像控件的内容,但它确实有效。当我在调用此方法后尝试相同时,它会打印为空白。
答案 0 :(得分:1)
我还没有在Windows 8中进行打印,但您可能需要使用BitmapImage或WriteableBitmap。 WinRT XAML工具包中有一些代码尚未以最佳性能方式执行,但应该适用于打印。它基本上归结为:
public static class WriteableBitmapRenderExtensions
{
public static async Task Render(this WriteableBitmap wb, FrameworkElement fe)
{
var ms = RenderToStream(fe);
var msrandom = new MemoryRandomAccessStream(ms);
await wb.SetSourceAsync(msrandom);
}
public static MemoryStream RenderToStream(FrameworkElement fe)
{
return new CompositionEngine().RenderToPngStream(fe);
}
}
public class CompositionEngine
{
private readonly ImagingFactory _wicFactory;
private readonly SharpDX.Direct2D1.Factory _d2DFactory;
private readonly SharpDX.DirectWrite.Factory _dWriteFactory;
public CompositionEngine()
{
_wicFactory = new ImagingFactory();
_d2DFactory = new SharpDX.Direct2D1.Factory();
this._dWriteFactory = new SharpDX.DirectWrite.Factory();
}
public ImagingFactory WicFactory
{
get
{
return this._wicFactory;
}
}
public SharpDX.Direct2D1.Factory D2DFactory
{
get
{
return this._d2DFactory;
}
}
public SharpDX.DirectWrite.Factory DWriteFactory
{
get
{
return this._dWriteFactory;
}
}
public MemoryStream RenderToPngStream(FrameworkElement fe)
{
var width = (int)Math.Ceiling(fe.ActualWidth);
var height = (int)Math.Ceiling(fe.ActualHeight);
// pixel format with transparency/alpha channel and RGB values premultiplied by alpha
var pixelFormat = WicPixelFormat.Format32bppPRGBA;
// pixel format without transparency, but one that works with Cleartype antialiasing
//var pixelFormat = WicPixelFormat.Format32bppBGR;
var wicBitmap = new Bitmap(
this.WicFactory,
width,
height,
pixelFormat,
BitmapCreateCacheOption.CacheOnLoad);
var renderTargetProperties = new RenderTargetProperties(
RenderTargetType.Default,
new D2DPixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied),
//new D2DPixelFormat(Format.Unknown, AlphaMode.Unknown), // use this for non-alpha, cleartype antialiased text
0,
0,
RenderTargetUsage.None,
FeatureLevel.Level_DEFAULT);
var renderTarget = new WicRenderTarget(
this.D2DFactory,
wicBitmap,
renderTargetProperties)
{
//TextAntialiasMode = TextAntialiasMode.Cleartype // this only works with the pixel format with no alpha channel
TextAntialiasMode = TextAntialiasMode.Grayscale // this is the best we can do for bitmaps with alpha channels
};
Compose(renderTarget, fe);
// TODO: There is no need to encode the bitmap to PNG - we could just copy the texture pixel buffer to a WriteableBitmap pixel buffer.
var ms = new MemoryStream();
var stream = new WICStream(
this.WicFactory,
ms);
var encoder = new PngBitmapEncoder(WicFactory);
encoder.Initialize(stream);
var frameEncoder = new BitmapFrameEncode(encoder);
frameEncoder.Initialize();
frameEncoder.SetSize(width, height);
var format = WicPixelFormat.Format32bppBGRA;
//var format = WicPixelFormat.FormatDontCare;
frameEncoder.SetPixelFormat(ref format);
frameEncoder.WriteSource(wicBitmap);
frameEncoder.Commit();
encoder.Commit();
frameEncoder.Dispose();
encoder.Dispose();
stream.Dispose();
ms.Position = 0;
return ms;
}
public void Compose(RenderTarget renderTarget, FrameworkElement fe)
{
renderTarget.BeginDraw();
Do your rendering here
renderTarget.Clear(new Color(0, 0, 0, 0));
Render(renderTarget, fe, fe);
renderTarget.EndDraw();
}
}