Encoding and decoding images in XNA Game Studio 4.0

In previous releases of XNA Game Studio, there were the Texture2D.Save and Texture2D.FromFile methods for encoding and decoding images, but they only worked on Windows. In XNA GS 4.0, we introduced a few new methods: Texture2D.SaveAsPng, Texture2D.SaveAsJpeg, and Texture2D.FromStream. These methods replace the old Save and FromFile methods and are available across all three of our platforms.

SaveAsPng and SaveAsJpeg both do as they say. You pass in the Stream to which the data should be written along with the size you want to save the image (useful for saving thumbnails of images by passing in values smaller than the actual texture).

Texture2D.FromStream supports decoding PNG, JPEG, and GIF data from a Stream object. There are two overloads of this method:

Texture2D.FromStream(GraphicsDevice graphicsDevice, Stream stream)

Texture2D.FromStream(GraphicsDevice graphicsDevice, Stream stream,
                     int width, int height, bool zoom)

The first overload should be pretty easy to understand as it simply decodes the image data from the stream and gives you back a Texture2D object.

The second overload takes in a maximum size along with a “zoom” value. If zoom is false, the resulting image will be scaled along its longer dimension to fit in the width and height. If zoom is true, the resulting image is scaled along its shorter dimension to fit in the width and height, cropping as necessary.

As an example, here’s the classic image of Shawn’s cat, found in many of our samples:

Shawn's cat

This image is 153x248. If we load the image in with Texture2D.FromStream passing in 100 for both the width and height and false for the zoom parameter, this is the resulting texture:

No zoom

This texture is 61x100. The longest dimension (the height) was scaled to our maximum height and aspect ratio was maintained.

Here’s what we see if we pass in true for the zoom parameter:

With zoom

This texture is 100x100. The shortest dimension (the width) was scaled to our maximum width and the image was cropped to fit in our 100x100 requested size.

A couple notes about Texture2D.FromStream:

  • The Texture2D you receive is always using SurfaceFormat.Color
  • The method does not handle color keys, premultiplied alpha, DXT compression, or mipmaps.

Texture2D.FromStream is useful for games that want to decode gamer pictures (which are now a Stream property instead of a Texture2D), album art (on Windows Phone), or user library pictures (on Windows Phone). It’s also nice to pair with the SaveAs* methods for saving and loading screenshots for games on any platform.

Tiny fun fact: the images you see above weren’t generated by me using a paint program; I actually loaded the texture with FromStream and saved out the images with SaveAsPng. So these are really the results you’d get. :)