How to edit an image (HTML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

This topic shows you how to use a BitmapEncoder to edit an existing image. You can use BitmapEncoder to apply transforms such as scaling and cropping, set metadata and properties, and edit pixels while preserving any unedited data. We show you how to initialize a BitmapEncoder with the original image data, apply one or more editing operations to it, and then save it so it updates the original file.

You can also use BitmapEncoder to create a new image from scratch, which we explain in How to encode a new image.

What you need to know

Technologies

Prerequisites

Instructions

Step 1: Get a decoder object from the original image

Write the beginning of a function that receives a BitmapEncoder object that was initialized from the image file that you want to edit, and the IRandomAccessStream opened from the file. This example overwrites the original image, so you must use a stream that was opened using ReadWrite privileges.

function (decoder, fileStream) {

Note  For instructions on how to obtain the decoder and stream objects, see How to decode an image.

 

When you call OpenAsync, make sure to change the FileAccessMode parameter to ReadWrite.

Step 2: Initialize the encoder object for editing

Create an InMemoryRandomAccessStream as the encoding destination and create a transcoding BitmapEncoder using the CreateForTranscodingAsync method.

Use the InMemoryRandomAccessStream as a temporary location to store the encoded file. Otherwise, the decoder and encoder would be simultaneously reading and writing to the same stream, which wouldn't work.

    // Keep variables in-scope across multiple async 
    var memStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
    var encoder;

    Windows.Graphics.Imaging.BitmapEncoder
    .createForTranscodingAsync(memStream, decoder).then(function (_encoder) {
        encoder = _encoder;

Note  CreateForTranscodingAsync supports copying data only to an image with the same format as the original. It doesn't allow you to convert from one format to another.

 

You now have a BitmapEncoder that has been initialized with the data from the source BitmapDecoder.

Step 3: Transform the image

Now that you have the encoder, you can perform a variety of actions including setting metadata and pixel data. This example scales and rotates the image using the BitmapTransform method. For more info about setting metadata, see How to write image metadata. For more info about setting pixel data, see How to encode a new image.

        // Scaling occurs before flip/rotation.
        encoder.bitmapTransform.scaledWidth = 640;
        encoder.bitmapTransform.scaledHeight = 480;

        // Fant is a relatively high quality interpolation algorithm.
        encoder.bitmapTransform.interpolationMode =
            Windows.Graphics.Imaging.BitmapInterpolationMode.fant;

        // Generate a new thumbnail from the updated pixel data.
        // Note: Only JPEG, TIFF and JPEG-XR images support encoding thumbnails.
        encoder.isThumbnailGenerated = true;

        encoder.bitmapTransform.rotation =
            Windows.Graphics.Imaging.BitmapRotation.clockwise90Degrees;

Note  If you use CreateForTranscodingAsync to create the BitmapEncoder, the encoder tries to copy over all of the original data in a lossless manner. For example, if you transcode a JPEG and edit some imaging properties, but don’t apply any transforms or edit the pixel data, the image is copied losslessly. But if you perform image processing by getting pixel data from the decoder and then setting it on the encoder, it is necessarily a lossy process as the pixel data must be re-encoded.

 

Step 4: Flush the encoder and handle errors

When you are finished using the encoder, flush it to complete the encoding operation. You also need to handle the case where the image format doesn’t support encoding thumbnails. If you know that you will always be editing an image format that supports thumbnails, like JPEG, then you can skip this error handling.

        return encoder.flushAsync();
    }).then(null, function (error) {
        switch (error.number) {
            // If the encoder doesn't support writing a thumbnail, then try again
            // but disable thumbnail generation.
            case -2003292287: // WINCODEC_ERR_UNSUPPORTEDOPERATION
                encoder.isThumbnailGenerated = false;
                return encoder.flushAsync();
            default:
                throw error;
        }

Step 5: Save the encoded image to the file and clean up

Finally, copy the contents from the in-memory stream to the original file’s stream and close all of the streams.

    }).then(function () {
        // Overwrite the contents of the file with the updated image stream.
        memStream.seek(0);
        fileStream.seek(0);
        fileStream.size = 0;
        return Windows.Storage.Streams.RandomAccessStream.copyAsync(memStream, fileStream);
    }).done(function () {
        memStream.close();
        fileStream.close();
    });

How to decode an image

How to encode an image

How to write image metadata