Search code examples
c#wpfbitmapimagebitmapsource

C# Converting BitmapSource to BitmapImage


I am trying to write a function that converts a BitmapSource to a BitmapImage. The only way I could find to do this was to create a temporary bmp file write and read from the file to create a new BitmapImage. This works fine until you try to delete the file or re-use the function. There are some file handling errors where the file will still be in use until the BitmapImage is freed.

1 - Is there a better way of converting BitmapSource to BitmapImages?

2 - What can I do to return the BitmapImage without freeing it?

public BitmapImage ConvertSourceToBitMapImage(BitmapSource bitmapSource)
{
    BitmapImage bmi = null;
    try
    {
        string filePath = @"C:\GitRepository\ReceiptAPP\ReceiptApplication\bin\Debug\testing.bmp";
        using (var fileStream = new FileStream(filePath, FileMode.Create))
        {
            BitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
            encoder.Save(fileStream);
            fileStream.Close();
        }
        Uri path = new Uri(filePath);
        bmi = new BitmapImage(path);
        File.Delete(filePath);
    }
    catch(Exception ex)
    {
    }
    return bmi;
}

enter image description here


Solution

  • Encoding to and decoding from a MemoryStream is a lot more efficient than a file.

    Note however that there is no use case for a conversion from BitmapSource to BitmapImage. A BitmapSource can directly be used as the Source of an Image element or as the ImageSource of an ImageBrush. You never explicitly need a BitmapImage.

    public static BitmapImage ConvertBitmapSourceToBitmapImage(
        BitmapSource bitmapSource)
    {
        // before encoding/decoding, check if bitmapSource is already a BitmapImage
    
        if (!(bitmapSource is BitmapImage bitmapImage))
        {
            bitmapImage = new BitmapImage();
    
            BmpBitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
    
            using (MemoryStream memoryStream = new MemoryStream())
            {
                encoder.Save(memoryStream);
                memoryStream.Position = 0;
    
                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.StreamSource = memoryStream;
                bitmapImage.EndInit();
            }
        }
    
        return bitmapImage;
    }