Search code examples
c#wpfimagesource

Show a rendered image of a UIelement(Visual) in an Image control WPF


I'm developing an application and I would like to implement a feature similar to Microsoft Power Point's paging system where there is a smaller image of the sheets you are working on on the side.

I have the following function which renders an image of the Grid in which the user has to work.

private void CreateImageOfPage()
    {
        int width = (int)this.WorkSheetViewModelList.Last().RootGrid.Width;
        int height = (int)this.WorkSheetViewModelList.Last().RootGrid.Height;
        RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
        renderTargetBitmap.Render(this.WorkSheetViewModelList.Last().RootGrid);
        PngBitmapEncoder pngImage = new PngBitmapEncoder();
        pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
        Guid photoID = System.Guid.NewGuid();

        String photolocation = "Temp/"+photoID.ToString() + ".png";
        using (var filestream = new FileStream(photolocation, FileMode.Create))
            encoder.Save(filestream);
        Console.WriteLine(Path.GetFullPath(photoID.ToString() + ".png"));
    }

My question is, how to get, set or format the path of the saved image to be set as Source of an Image in a XAML? In its current form the path looks like this : "D:\Project\bin\Debug\7fd77420-f62e-44e7-b206-b5ce19f01a9e.png", and it says it could not get the file at this location(for now I just copied the output in, but it will be bound, as it should be).

If the path I've taken is not elegant, is there any other way to do it better, or without saving the image to the disk at all?

Thanks!


Solution

  • You don't need to do any image encoding.

    Assuming that there is an Image element named image, you could directly assign the RenderTargetBitmap to its Source property like this:

    image.Source = renderTargetBitmap;
    

    You may change your method to this:

    private ImageSource CreateImageOfPage()
    {
        var rootGrid = WorkSheetViewModelList.Last().RootGrid;
        var width = (int)rootGrid.ActualWidth;
        var height = (int)rootGrid.ActualHeight;
        var renderTargetBitmap = new RenderTargetBitmap(
            width, height, 96, 96, PixelFormats.Pbgra32);
        renderTargetBitmap.Render(rootGrid);
        return renderTargetBitmap;
    }
    

    and use it like this:

    image.Source = CreateImageOfPage();