6

セットアップ

Direct *ライブラリのマネージラッパーであるSharpDXを使用して、ビットマップをレンダリングし、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")));
        }
    }
}

このプログラムを実行すると、プログラムの作業ディレクトリに「test.png」ファイルが作成され、次の美しい画像が表示されます。

出力画像

質問

素晴らしいです。GDI+の代わりにDirect2Dを使用して画像をレンダリングしました。これは、ASP.NETアプリケーションのコンテキストでよりサポートされていると思われます。さらに、Direct2Dは新しい注目度です。

Streamこのような画像をレンダリングし、PNGをまたはbyte[]配列として返し、ファイルシステムに書き込む代わりに、レンダリングおよびエンコード操作全体をメモリ内で実行する関数を作成したいとします。これは、Web要求に応答するためのものです。ファイルシステムを経由せずにブラウザに直接ストリーミングするのは理にかなっています。

GDI +では、これをMemoryStream非常に簡単に行うことができDataStreamましたが、バッファのサイズを知らなければ、SharpDXでの使用方法を理解することはできません。

        var bufferSize = 1024 * 3; // how do I know?
        var buffer = new DataStream(
            bufferSize,
            true,
            true);
        var stream = new WICStream(
            wicFactory,
            buffer);
  • P / Invokeを実行しCreateStreamOnHGlobal、それを使用しIntPtrてビルドする必要がありますDataStreamか?
  • DataStream私が見逃している過負荷はありますか?
  • エンコードされたPNG画像を保持するために必要なバッファを事前に計算する簡単な方法はありますか?
  • それとも、ファイルシステムの処理をやり直す必要がありますか?

助けてくれてありがとう!

4

2 に答える 2

4

ライブラリの作成者は、これを機能として追加しました

コードは人々に役立つDirect2Dサンプルを提供すると思うので、質問は残しておきます。

于 2012-02-06T03:01:55.783 に答える
3

誰かがasp.netでこれを行うことを探している場合:

var memStream = new MemoryStream();
var wicStream = new WICStream(wicFactory, memStream);

//Encode wic bitmap
var encoder = new PngBitmapEncoder(wicFactory);
encoder.Initialize(wicStream);
var frameEncoder = new BitmapFrameEncode(encoder);
frameEncoder.Initialize();
frameEncoder.SetSize(width, height);
var format = WicPixelFormat.FormatDontCare;
frameEncoder.SetPixelFormat(ref format);
frameEncoder.WriteSource(wicBitmap);
frameEncoder.Commit();
encoder.Commit();

//Clean-up
frameEncoder.Dispose();
encoder.Dispose();
wicStream.Dispose();

imgBackdrop.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(memStream.ToArray(), 0, memStream.ToArray().Length);
于 2014-05-17T12:49:12.317 に答える