Search code examples
c#wpfimageuniformgrid

Saving Images in UniformGrid in WPF


I need to save images, which I have in UniformGrid. It is possible or not? I'm using UniformGrid, because if I'm expanding the Window, Image adapt to UniformGrid size (is responsible). Do you have any ideas please?


Solution

  • In WinForms have the option to save the System.Drawing.Image directly to a file, like this:

    MyImage.Save("C:\\myBitmap.bmp");
    

    As far as I know, this is not possible in WPF. But there is a more dynamic way, using RenderTargetBitmap you can save any visual element in the form of images.

    In this question:

    Save content of a visual Object as a image file in WPF?

    I found the methods that allow save visual element in JPG. I combined them into a static class WorkWithImages:

    public static class WorkWithImages 
    {
        public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
        {
            var scale = resolution / 96d;
            uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            var sz = uiElement.DesiredSize;
            var rect = new Rect(sz);
            uiElement.Arrange(rect);
            var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
            bmp.Render(uiElement);
    
            return bmp;
        }
    
        public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
        {
            var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));
    
            if (path != null)
            {
                try
                {
                    using (var fileStream = File.Create(path))
                    {
                        using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
                        {
                            streamWriter.Write(jpegString);
                            streamWriter.Close();
                        }
    
                        fileStream.Close();
                    }
                }
    
                catch (Exception ex)
                {
                    //TODO: handle exception here
                }
            }
        }
    
        private static string CreateJpeg(RenderTargetBitmap bitmap)
        {
            var jpeg = new JpegBitmapEncoder();
            jpeg.Frames.Add(BitmapFrame.Create(bitmap));
            string result;
    
            using (var memoryStream = new MemoryStream())
            {
                jpeg.Save(memoryStream);
                memoryStream.Seek(0, SeekOrigin.Begin);
    
                using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
                {
                    result = streamReader.ReadToEnd();
                    streamReader.Close();
                }
    
                memoryStream.Close();
            }
    
            return result;
        }
    }
    

    And here is a complete example:

    XAML

    <Grid>
        <Label Name="TestLabel"
               Content="Test" 
               Width="100" 
               Height="100"
               HorizontalContentAlignment="Center"
               VerticalContentAlignment="Center"
               Background="Beige" />
    
        <StackPanel>
            <Button Name="SaveToJpgButton"
                    Width="100" 
                    Height="30" 
                    Content="SaveToJpg"
                    Click="SaveToJpg_Click" />
        </StackPanel>
    </Grid>
    

    Code-behind

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void SaveToJpg_Click(object sender, RoutedEventArgs e)
        {
            WorkWithImages.ConvertToJpeg(TestLabel, "TestLabel.jpg", 132);
        }       
    }
    
    public static class WorkWithImages 
    {
        public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
        {
            var scale = resolution / 96d;
            uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            var sz = uiElement.DesiredSize;
            var rect = new Rect(sz);
            uiElement.Arrange(rect);
            var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
            bmp.Render(uiElement);
    
            return bmp;
        }
    
        public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
        {
            var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));
    
            if (path != null)
            {
                try
                {
                    using (var fileStream = File.Create(path))
                    {
                        using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
                        {
                            streamWriter.Write(jpegString);
                            streamWriter.Close();
                        }
    
                        fileStream.Close();
                    }
                }
    
                catch (Exception ex)
                {
                    //TODO: handle exception here
                }
            }
        }
    
        private static string CreateJpeg(RenderTargetBitmap bitmap)
        {
            var jpeg = new JpegBitmapEncoder();
            jpeg.Frames.Add(BitmapFrame.Create(bitmap));
            string result;
    
            using (var memoryStream = new MemoryStream())
            {
                jpeg.Save(memoryStream);
                memoryStream.Seek(0, SeekOrigin.Begin);
    
                using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
                {
                    result = streamReader.ReadToEnd();
                    streamReader.Close();
                }
    
                memoryStream.Close();
            }
    
            return result;
        }
    }