2015-09-15 3 views
1

Je crée un programme ressemblant à de la peinture en utilisant Win2D. Mon CanvasControl contient du texte, des images et certaines lignes que l'utilisateur a dessinées. Je veux enregistrer tout le contenu de ce CanvasControl en tant que fichier sur le disque (dans n'importe quel format d'image standard). Je veux faire cela comme je veux l'afficher (à un moment ultérieur) à l'intérieur d'un contrôle Image standard.Comment enregistrer le contenu de CanvasControl en tant que fichier image

Comment est-ce que je ferais ceci? J'ai essayé d'utiliser RenderTargetBitmap pour charger le CanvasControl (code ci-dessous), mais pour une raison quelconque, il clips l'image et seulement une petite image de la partie supérieure horizontale est faite.


async private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     #region (c) rendering UIElement to bitmap code 

     var bitmap = new RenderTargetBitmap(); 
     await bitmap.RenderAsync(ccDraw); // ccDraw is CanvasControl 

     // get the pixels 
     IBuffer pixelBuffer = await bitmap.GetPixelsAsync(); 
     byte[] pixels = pixelBuffer.ToArray(); 

     // write the pixels to a InMemoryRandomAccessStream 
     var stream = new InMemoryRandomAccessStream(); 
     var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream); 
     encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, pixels); 

     await encoder.FlushAsync(); 
     stream.Seek(0); 

     Image iNew = new Image(); 
     iNew.Stretch = Stretch.None; 
     iNew.Source = bitmap; 
     gOuter.Children.Add(iNew); 
     ccDraw.Visibility = Visibility.Collapsed; // hide CanvasControl so we can see added image 

    #endregion 
    } 
+0

Pouvez-vous afficher du code, où vous avez essayé 'RenderTargetBitmap'? – RenDishen

+0

@RenDishen J'ai ajouté le code que j'utilise –

+0

Vérifiez ma réponse ci-dessous. Je pense que vous disiez essentiellement que vous voulez enregistrer la toile comme une image correcte? – thewisegod

Répondre

1

Voici comment je l'ai fait pour moi. imageSize est la taille de l'image, par exemple var imageSize = new Size(500,500);

var displayInformation = DisplayInformation.GetForCurrentView(); 

ccDraw.Measure(imageSize); 
ccDraw.UpdateLayout(); 
ccDraw.Arrange(new Rect(0, 0, imageSize.Width, imageSize.Height)); 

var renderTargetBitmap = new RenderTargetBitmap(); 
await renderTargetBitmap.RenderAsync(ccDraw, Convert.ToInt32(imageSize.Width), Convert.ToInt32(imageSize.Height)); 

var pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); 
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Screen.jpg", CreationCollisionOption.ReplaceExisting); 
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) 
{ 
     var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, fileStream); 

     encoder.SetPixelData(
       BitmapPixelFormat.Bgra8, 
       BitmapAlphaMode.Ignore, 
       (uint)renderTargetBitmap.PixelWidth, 
       (uint)renderTargetBitmap.PixelHeight, 
       displayInformation.LogicalDpi, 
       displayInformation.LogicalDpi, 
       pixelBuffer.ToArray()); 

     await encoder.FlushAsync(); 
} 
0

Essayez ceci:

private void SaveCanvasAsImage() 
    { 
     Rect yourRect = new Rect(ccDraw.RenderSize); 
     RenderTargetBitmap rtBitmap = new RenderTargetBitmap((int)yourRect.Right, 
     (int)yourRect.Bottom, 100d, 100d, System.Windows.Media.PixelFormats.Default); 
     rtBitmap.Render(ccDraw); 

     BitmapEncoder pngEncoder = new PngBitmapEncoder(); 
     pngEncoder.Frames.Add(BitmapFrame.Create(rtBitmap)); 

     System.IO.MemoryStream ms = new System.IO.MemoryStream(); 

     pngEncoder.Save(ms); 
     ms.Close(); 
     System.IO.File.WriteAllBytes("yourPng.png", ms.ToArray()); 
    } 
+0

Merci, mais il ne semble pas entrer dans une application Windows Store/WinRT. Est-ce que ce code WPF? Il dit que 'RenderTargetBitmap' n'a pas de définition pour la méthode' Render'. –

+0

Oui, c'est WPF désolé. – thewisegod

0

Vous ne pouvez pas enregistrer directement le contenu d'un CanvasControl. Toutefois, si vous dessinez sur un CanvasRenderTarget intermédiaire, vous pouvez l'enregistrer en utilisant SaveAsync.

Vous trouverez plus d'informations sur le dessin hors écran au http://microsoft.github.io/Win2D/html/Offscreen.htm. Il y a d'autres avantages à dessiner sur CanvasRenderTarget plutôt que de dessiner directement sur CanvasControl - le plus évident est qu'il vous permet de faire un rendu additif, plutôt que d'avoir à redessiner l'affichage entier à chaque fois.

+1

Merci, je vais devoir tirer hors écran aussi. Mais j'ai été capable d'obtenir un fichier image de son contenu (composé de lignes, n'a pas testé les images) en utilisant le code que RenDishen avait mentionné. –

+1

Aucune idée de pourquoi cette réponse a été downvoted. –