简体   繁体   中英

How to draw text on an image and save it using UWP (for Windows 10)

I want to draw text on a template image in UWP (for Windows 10), and then be able to save the image (so the user could print or share it).

I have played around with the canvas control and even the Win2D package from nuget. Any suggestions as to what the best way to do this are appreciated. Sample code of where I left off is below.

XAML

<Page
x:Class="DrawTextExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DrawTextExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Button Name="btnSaveImage" Content="Save the image" Margin="10" Click="btnSaveImage_Click" />

    <Grid Name="MyCreatedImage">
        <Image Name="imgName" Stretch="UniformToFill" Source="Assets/HelloMyNameIs.jpg" />
        <TextBlock Name="lblName" Text="McFly" Margin="20,100,20,20" FontSize="36"/>
    </Grid>
</StackPanel>

Code Behind

using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace DrawTextExample {
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void btnSaveImage_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) {
            var bitmap = new RenderTargetBitmap();
            await bitmap.RenderAsync(MyCreatedImage);
        }
    }
}

Image (HelloMyNameIs.jpg) 你好我的名字是

I want to draw text on a template image in UWP (for Windows 10), and then be able to save the image (so the user could print or share it).

According to your code snippet, you are trying to use RenderTargetBitmap which can meet your requirements. This class can render the Image with the TextBlock together into one image. Your code snippet just lack of saving. You can save the rendered image as follows:

private async void btnSaveImage_Click(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(MyCreatedImage);

    var pixelBuffer = await bitmap.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();
    var displayInformation = DisplayInformation.GetForCurrentView();
    StorageFolder pictureFolder = KnownFolders.SavedPictures;
    var file = await pictureFolder.CreateFileAsync("test2.jpg", CreationCollisionOption.ReplaceExisting);
    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                             BitmapAlphaMode.Premultiplied,
                             (uint)bitmap.PixelWidth,
                             (uint)bitmap.PixelHeight,
                             displayInformation.RawDpiX,
                             displayInformation.RawDpiY,
                             pixels);
        await encoder.FlushAsync();
    }
}

You may also try to use Win2D which may be recommended. You can draw images, draw text and draw shapes as you want. It provides the CanvasBitmap.SaveAsync method for saving the result. For example, the following demo showed how to draw the text on the image and save it to the picture folder.

Uri imageuri = new Uri("ms-appx:///Assets/HelloMyNameIs.jpg");
StorageFile inputFile = await StorageFile.GetFileFromApplicationUriAsync(imageuri);
BitmapDecoder imagedecoder;
using (var imagestream = await inputFile.OpenAsync(FileAccessMode.Read))
{
    imagedecoder =await BitmapDecoder.CreateAsync(imagestream);
}  
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, imagedecoder.PixelWidth, imagedecoder.PixelHeight, 96);
using (var ds = renderTarget.CreateDrawingSession())
{
    ds.Clear(Colors.White);
    CanvasBitmap image = await CanvasBitmap.LoadAsync(device, inputFile.Path, 96);
    ds.DrawImage(image);
    ds.DrawText(lblName.Text, new System.Numerics.Vector2(150, 150), Colors.Black);
}
string filename = "test1.png";
StorageFolder pictureFolder = KnownFolders.SavedPictures;
var file = await pictureFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
    await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
}

If you want personality text drawing on the image you may consider using InkCanvas to DrawInk . Details you may reference this thread .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM