|
using System;
using System.IO;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DirectWrite;
using SharpDX.DXGI;
using SharpDX.WIC;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Bitmap = SharpDX.WIC.Bitmap;
using D2DPixelFormat = SharpDX.Direct2D1.PixelFormat;
using WicPixelFormat = SharpDX.WIC.PixelFormat;
using Windows.Graphics.Display;
using Windows.Storage;
using Windows.Media.Capture;
using System.Threading.Tasks;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace RenderTextToBitmap
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
//
// http://stackoverflow.com/questions/9151615/how-does-one-use-a-memory-stream-instead-of-files-when-rendering-direct2d-images
//
// Identical to above SO question, except that we are rendering to MemoryStream because it was added to the API
//
public static SharpDX.WIC.BitmapSource LoadBitmap(ImagingFactory2 factory, string ImageFilePath)
{
var bitmapDecoder = new BitmapDecoder(
factory,
ImageFilePath,
DecodeOptions.CacheOnDemand
);
var formatConverter = new FormatConverter(factory);
formatConverter.Initialize(
bitmapDecoder.GetFrame(0),
SharpDX.WIC.PixelFormat.Format32bppPRGBA,
BitmapDitherType.None,
null,
0.0,
BitmapPaletteType.Custom);
return formatConverter;
}
private async Task<MemoryStream> RenderStaticTextToBitmap(StorageFile ImageFile)
{
var bitmap = new BitmapImage();
using (var strm = await ImageFile.OpenAsync(FileAccessMode.Read))
{
bitmap.SetSource(strm);
}
var width = bitmap.PixelWidth;
var height = bitmap.PixelHeight;
var pixelFormat = WicPixelFormat.Format32bppBGR;
var wicFactory = new ImagingFactory2();
var dddFactory = new SharpDX.Direct2D1.Factory();
var dwFactory = new SharpDX.DirectWrite.Factory();
WicRenderTarget renderTarget;
Bitmap wicBitmap;
using (var bitmapSource = LoadBitmap(wicFactory, ImageFile.Path))
{
wicBitmap = new Bitmap(wicFactory, bitmapSource, BitmapCreateCacheOption.CacheOnLoad);
int pixelWidth = (int)(wicBitmap.Size.Width * DisplayProperties.LogicalDpi / 96.0);
int pixelHeight = (int)(wicBitmap.Size.Height * DisplayProperties.LogicalDpi / 96.0);
var renderTargetProperties = new RenderTargetProperties(RenderTargetType.Default,
new D2DPixelFormat(Format.Unknown, AlphaMode.Unknown), 0, 0, RenderTargetUsage.None,
FeatureLevel.Level_DEFAULT);
renderTarget = new WicRenderTarget(
dddFactory,
wicBitmap,
renderTargetProperties)
{
TextAntialiasMode = TextAntialiasMode.Cleartype
};
}
renderTarget.BeginDraw();
var textFormat = new TextFormat(dwFactory, "Segoe UI Light", 25)
{
TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading,
ParagraphAlignment = ParagraphAlignment.Far
};
var textBrush = new SharpDX.Direct2D1.SolidColorBrush(
renderTarget,
SharpDX.Colors.Red);
renderTarget.DrawText(
DateTime.Now.ToString("t") + "\n" + DateTime.Now.ToString("d") + "\n",
textFormat,
new RectangleF(width - 150, 0, width, height + 25),
textBrush);
renderTarget.EndDraw();
var ms = new MemoryStream();
var stream = new WICStream(
wicFactory,
ms);
BitmapEncoder encoder = null;
if (ImageFile.FileType == ".png")
encoder = new PngBitmapEncoder(wicFactory);
else if (ImageFile.FileType == ".jpg")
encoder = new JpegBitmapEncoder(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();
ms.Position = 0;
return ms;
}
private async void Render_OnClick(object sender, RoutedEventArgs e)
{
try
{
var dialog = new CameraCaptureUI();
dialog.PhotoSettings.AllowCropping = true;
var ImageFile = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (ImageFile == null)
return;
var ms = await RenderStaticTextToBitmap(ImageFile);
var msrandom = new MemoryRandomAccessStream(ms);
Byte[] bytes = new Byte[ms.Length];
await ms.ReadAsync(bytes, 0, (int)ms.Length);
StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync("Image.png", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
using (var strm = await file.OpenStreamForWriteAsync())
{
await strm.WriteAsync(bytes, 0, bytes.Length);
strm.Flush();
}
BitmapImage image = new BitmapImage();
await image.SetSourceAsync(msrandom);
RenderedImage.Source = image;
}
catch (Exception)
{
//TODO: Log the error.
throw;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Leading a passionate team to build metadata driven generic IoT Platform using for the operating companies (OpCos) of a Fortune 500 American conglomerate manufacturer of industrial products having annual revenue over $7 billion. Willing to join product-based and SaaS companies having production workloads and serving end customers happily.