设置
考虑使用SharpDX(Direct* 库的托管包装器)的给定临时程序来呈现位图并将其保存为 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”文件,其中包含以下漂亮的图像:
问题
太棒了,我刚刚使用 Direct2D 而不是 GDI+ 渲染了一个图像,据说在 ASP.NET 应用程序的上下文中更受支持。另外,Direct2D 是新的热点。
假设我想编写一个函数来渲染这样的图像并将 PNG 作为 aStream
或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 图像所需的必要缓冲区?
- 或者我应该只是通过文件系统克服?
谢谢你的帮助!