Create, edit, and save bitmap images
May 22, 2026 ยท View on GitHub
This article explains how to load and save image files using BitmapDecoder and BitmapEncoder and how to use the SoftwareBitmap object to represent bitmap images.
The SoftwareBitmap class is a versatile API that can be created from multiple sources including image files, WriteableBitmap objects, Direct3D surfaces, and code. SoftwareBitmap allows you to easily convert between different pixel formats and alpha modes, and allows low-level access to pixel data. Also, SoftwareBitmap is a common interface used by multiple features of Windows, including:
-
CapturedFrame allows you to get frames captured by the camera as a SoftwareBitmap.
-
VideoFrame allows you to get a SoftwareBitmap representation of a VideoFrame.
-
FaceDetector allows you to detect faces in a SoftwareBitmap.
The sample code in this article uses APIs from the following namespaces.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetNamespaces":::
Create a SoftwareBitmap from an image file with BitmapDecoder
To create a SoftwareBitmap from a file, get an instance of StorageFile containing the image data. This example uses a FileOpenPicker to allow the user to select an image file.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetPickInputFile":::
Call the OpenAsync method of the StorageFile object to get a random access stream containing the image data. Call the static method BitmapDecoder.CreateAsync to get an instance of the BitmapDecoder class for the specified stream. Call GetSoftwareBitmapAsync to get a SoftwareBitmap object containing the image.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetCreateSoftwareBitmapFromFile":::
Save a SoftwareBitmap to a file with BitmapEncoder
To save a SoftwareBitmap to a file, get an instance of StorageFile to which the image will be saved. This example uses a FileSavePicker to allow the user to select an output file.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetPickOutputFile":::
Call the OpenAsync method of the StorageFile object to get a random access stream to which the image will be written. Call the static method BitmapEncoder.CreateAsync to get an instance of the BitmapEncoder class for the specified stream. The first parameter to CreateAsync is a GUID representing the codec that should be used to encode the image. BitmapEncoder class exposes a property containing the ID for each codec supported by the encoder, such as JpegEncoderId.
Use the SetSoftwareBitmap method to set the image that will be encoded. You can set values of the BitmapTransform property to apply basic transforms to the image while it is being encoded. The IsThumbnailGenerated property determines whether a thumbnail is generated by the encoder. Note that not all file formats support thumbnails, so if you use this feature, you should catch the unsupported operation error that will be thrown if thumbnails are not supported.
Call FlushAsync to cause the encoder to write the image data to the specified file.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetSaveSoftwareBitmapToFile":::
You can specify additional encoding options when you create the BitmapEncoder by creating a new BitmapPropertySet object and populating it with one or more BitmapTypedValue objects representing the encoder settings. For a list of supported encoder options, see BitmapEncoder options reference.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetUseEncodingOptions":::
Use SoftwareBitmap with a XAML Image control
To display an image within a XAML page using the Image control, first define an Image control in your XAML page.
:::code language="xml" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml" id="SnippetImageControl":::
Currently, the Image control only supports images that use BGRA8 encoding and pre-multiplied or no alpha channel. Before attempting to display an image, test to make sure it has the correct format, and if not, use the SoftwareBitmap static Convert method to convert the image to the supported format.
Create a new SoftwareBitmapSource object. Set the contents of the source object by calling SetBitmapAsync, passing in a SoftwareBitmap. Then you can set the Source property of the Image control to the newly created SoftwareBitmapSource.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetSoftwareBitmapToWriteableBitmap":::
You can also use SoftwareBitmapSource to set a SoftwareBitmap as the ImageSource for an ImageBrush.
Create a SoftwareBitmap from a WriteableBitmap
You can create a SoftwareBitmap from an existing WriteableBitmap by calling SoftwareBitmap.CreateCopyFromBuffer and supplying the PixelBuffer property of the WriteableBitmap to set the pixel data. The second argument lets you specify the pixel format for the newly created SoftwareBitmap. You can use the PixelWidth and PixelHeight properties of the WriteableBitmap to specify the dimensions of the new image.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetWriteableBitmapToSoftwareBitmap":::
Create or edit a SoftwareBitmap programmatically
So far this topic has addressed working with image files. You can also create a new SoftwareBitmap programmatically in code and use the same technique to access and modify the SoftwareBitmap's pixel data.
Use the CopyFromBuffer method to populate a SoftwareBitmap from a byte array, and CopyToBuffer to copy pixel data out to a byte array for reading or modification. To use the AsBuffer extension method to wrap a byte array as an IBuffer, include the System.Runtime.InteropServices.WindowsRuntime namespace (this is included in the SnippetNamespaces using statements at the top of this article).
Create a new SoftwareBitmap with the pixel format and size you want. Allocate a byte array large enough to hold the pixel data, fill it with the desired values, and then call CopyFromBuffer to write the data into the bitmap.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetCreateNewSoftwareBitmap":::
Create a SoftwareBitmap from a Direct3D surface
To create a SoftwareBitmap object from a Direct3D surface, you must include the Windows.Graphics.DirectX.Direct3D11 namespace in your project.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetDirect3DNamespace":::
Call CreateCopyFromSurfaceAsync to create a new SoftwareBitmap from the surface. As the name indicates, the new SoftwareBitmap has a separate copy of the image data. Modifications to the SoftwareBitmap will not have any effect on the Direct3D surface.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetCreateSoftwareBitmapFromSurface":::
Convert a SoftwareBitmap to a different pixel format
The SoftwareBitmap class provides the static method, Convert, that allows you to easily create a new SoftwareBitmap that uses the pixel format and alpha mode you specify from an existing SoftwareBitmap. Note that the newly created bitmap has a separate copy of the image data. Modifications to the new bitmap will not affect the source bitmap.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetConvert":::
Transcode an image file
You can transcode an image file directly from a BitmapDecoder to a BitmapEncoder. Create a IRandomAccessStream from the file to be transcoded. Create a new BitmapDecoder from the input stream. Create a new InMemoryRandomAccessStream for the encoder to write to and call BitmapEncoder.CreateForTranscodingAsync, passing in the in-memory stream and the decoder object. Encode options are not supported when transcoding; instead you should use CreateAsync. Any properties in the input image file that you do not specifically set on the encoder, will be written to the output file unchanged. Call FlushAsync to cause the encoder to encode to the in-memory stream. Finally, seek the file stream and the in-memory stream to the beginning and call CopyAsync to write the in-memory stream out to the file stream.
:::code language="csharp" source="~/../snippets-windows/winappsdk/audio-video-camera/imaging-winui/cs/ImagingWinUI/MainWindow.xaml.cs" id="SnippetTranscodeImageFile":::