通过SharpDX渲染Direct2D图像时,如何使用内存流而不是文件? [英] How does one use a memory stream instead of files when rendering Direct2D images via SharpDX?

查看:127
本文介绍了通过SharpDX渲染Direct2D图像时,如何使用内存流而不是文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置

考虑给定的临时程序,该程序使用.另外,Direct2D是新的亮点.

比方说,我想编写一个渲染此类图像并以 MemoryStream 非常容易,但是我不知道如何在SharpDX中使用 DataStream 来发挥我的优势,而又不知道缓冲区的大小:

  var bufferSize = 1024 * 3;//我怎么知道?var buffer = new DataStream(缓冲区大小,真的,真的);var stream = new WICStream(wicFactory,缓冲); 

  • 我是否必须P/Invoke以 CreateStreamOnHGlobal 并使用该 IntPtr 构建我的 DataStream ?
  • 我是否缺少 DataStream 的重载?
  • 是否有一种简单的方法来预先计算保存编码的PNG图像所需的必要缓冲区?
  • 还是我应该遍历文件系统?

感谢您的帮助!

解决方案

库的作者将此功能添加为功能.

我会解决这个问题,因为我认为代码为人们提供了有用的Direct2D示例.

The setup

Consider the given scratch program that uses SharpDX, a managed wrapper for Direct* libraries, to render a bitmap and save it as a PNG:

namespace ConsoleApplication5
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using SharpDX;
    using SharpDX.Direct2D1;
    using SharpDX.DirectWrite;
    using SharpDX.DXGI;
    using SharpDX.IO;
    using SharpDX.WIC;
    using AlphaMode = SharpDX.Direct2D1.AlphaMode;
    using Bitmap = SharpDX.WIC.Bitmap;
    using D2DPixelFormat = SharpDX.Direct2D1.PixelFormat;
    using WicPixelFormat = SharpDX.WIC.PixelFormat;

    class Program
    {
        static void Main(string[] args)
        {
            var width = 400;
            var height = 100;
            var pixelFormat = WicPixelFormat.Format32bppBGR;

            var wicFactory = new ImagingFactory();
            var dddFactory = new SharpDX.Direct2D1.Factory();
            var dwFactory = new SharpDX.DirectWrite.Factory();

            var wicBitmap = new Bitmap(
                wicFactory,
                width,
                height,
                pixelFormat,
                BitmapCreateCacheOption.CacheOnLoad);

            var renderTargetProperties = new RenderTargetProperties(
                RenderTargetType.Default,
                new D2DPixelFormat(Format.Unknown, AlphaMode.Unknown),
                0,
                0,
                RenderTargetUsage.None,
                FeatureLevel.Level_DEFAULT);
            var renderTarget = new WicRenderTarget(
                dddFactory,
                wicBitmap,
                renderTargetProperties)
            {
                TextAntialiasMode = TextAntialiasMode.Cleartype
            };

            renderTarget.BeginDraw();

            var textFormat = new TextFormat(dwFactory, "Consolas", 48) 
            {
                TextAlignment = TextAlignment.Center, 
                ParagraphAlignment = ParagraphAlignment.Center
            };
            var textBrush = new SolidColorBrush(
                renderTarget,
                Colors.Blue);

            renderTarget.Clear(Colors.White);
            renderTarget.DrawText(
                "Hi, mom!",
                textFormat,
                new RectangleF(0, 0, width, height),
                textBrush);

            renderTarget.EndDraw();

            var stream = new WICStream(
                wicFactory,
                "test.png",
                NativeFileAccess.Write);

            var encoder = new PngBitmapEncoder(wicFactory);
            encoder.Initialize(stream);

            var frameEncoder = new BitmapFrameEncode(encoder);
            frameEncoder.Initialize();
            frameEncoder.SetSize(width, height);
            frameEncoder.PixelFormat = WicPixelFormat.FormatDontCare;
            frameEncoder.WriteSource(wicBitmap);
            frameEncoder.Commit();

            encoder.Commit();

            frameEncoder.Dispose();
            encoder.Dispose();
            stream.Dispose();

            Process.Start(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "test.png")));
        }
    }
}

Running this program gives you a "test.png" file in the program's working directory with the following beautiful image:

The question

Awesome, I've just rendered an image using Direct2D instead of GDI+, which is supposedly more supported in the context of an ASP.NET application. Plus, Direct2D is the new hotness.

Let's say that I wanted to write a function that rendered such an image and returned the PNG as a Stream or a byte[] array, performing the entire rendering and encoding operation in memory instead of writing to the file system. This is for a responding to a Web request; makes sense just to stream it out straight to the browser without going through the file system.

In GDI+, I could do this with a MemoryStream pretty easily, but I can't figure out how to use DataStream in SharpDX to my advantage without knowing the size of the buffer:

        var bufferSize = 1024 * 3; // how do I know?
        var buffer = new DataStream(
            bufferSize,
            true,
            true);
        var stream = new WICStream(
            wicFactory,
            buffer);

  • Do I have to P/Invoke to CreateStreamOnHGlobal and use that IntPtr to build my DataStream?
  • Is there some overload of DataStream that I am missing?
  • Is there an easy way to pre-calculate the necessary buffer needed to hold the encoded PNG image?
  • Or should I just get over going through the file system?

Thanks for any help!

解决方案

The author of the library added this as a feature.

I'll leave the question around as I think the code provides a useful Direct2D sample for people.

这篇关于通过SharpDX渲染Direct2D图像时,如何使用内存流而不是文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆