【问题标题】:How to print the content rendered to SurfaceImageSource?如何打印渲染到 SurfaceImageSource 的内容?
【发布时间】:2012-12-12 13:20:36
【问题描述】:

我正在使用 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);
        }

    }

我尝试在不执行这些渲染操作的情况下打印图像控件的内容,它成功了。当我在调用此方法后尝试相同时,它打印为空白。

【问题讨论】:

    标签: c# printing windows-runtime directx sharpdx


    【解决方案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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-11
      • 2016-08-04
      • 2012-09-02
      • 2017-07-12
      • 1970-01-01
      • 2020-08-26
      • 2013-06-09
      • 2015-02-27
      相关资源
      最近更新 更多