# Reading images

There are several ways to open images:

- To open an image file

- To read a input stream (file-like object) that provides an image binary

- To read a binary string that contains image

- To copy an existing image object

- To open an empty image

All of these operations are provided by the constructor of `Image` class.

## Open an image file

The most frequently used way is just to open an image by its filename. `Image`’s constructor can take the parameter named `filename`:

    from wand.image import Image

    with Image(filename='pikachu.png') as img:
        print('width =', img.width)
        print('height =', img.height)

Note

It must be passed by keyword argument exactly. Because the constructor has many parameters that are exclusive to each other.

There is a keyword argument named `file` as well, but don’t confuse it with `filename`. While `filename` takes a string of a filename, `file` takes a input stream (file-like object).

## Read an input stream

If an image to open cannot be located by a filename but can be read through input stream interface (e.g. opened by `os.popen()`, contained in `StringIO`, read by `urllib2.urlopen()`), it can be read by `Image` constructor’s `file` parameter. It takes all file-like objects which implements `read()` method:

    from urllib2 import urlopen
    from wand.image import Image

    response = urlopen('https://stylesha.re/minhee/29998/images/100x100')
    try:
        with Image(file=response) as img:
            print('format =', img.format)
            print('size =', img.size)
    finally:
        response.close()

In the above example code, `response` object returned by `urlopen()` function has `read()` method, so it also can be used as an input stream for a downloaded image.

## Read a blob

If you have just a binary string (`bytes`) of the image, you can pass it into `Image` constructor’s `blob` parameter to read:

    from wand.image import Image

    with open('pikachu.png', 'rb') as f:
        image_binary = f.read()

    with Image(blob=image_binary) as img:
        print('width =', img.width)
        print('height =', img.height)

It is a way of the lowest level to read an image. There will probably not be many cases to use it.

## Clone an image

If you have an image already and have to copy it for safe manipulation, use `clone()` method:

    from wand.image import Image

    with Image(filename='pikachu.png') as original:
        with original.clone() as converted:
            converted.format = 'png'
            # operations on a converted image...

For some operations like format converting or cropping, there are safe methods that return a new image of manipulated result like `convert()` or slicing operator. So the above example code can be replaced by:

    from wand.image import Image

    with Image(filename='pikachu.png') as original:
        with original.convert('png') as converted:
            # operations on a converted image...

## Hint file format

When it’s read from a binary string or a file object, you can explicitly give the hint which indicates file format of an image to read — optional `format` keyword is for that:

    from wand.image import Image

    with Image(blob=image_binary, format='ico') as image:
        print(image.format)

Added in version 0.2.1: The `format` parameter to `Image` constructor.

## Open an empty image

To open an empty image, you have to set its width and height:

    from wand.image import Image

    with Image(width=200, height=100) as img:
        img.save(filename='200x100-transparent.png')

Its background color will be transparent by default. You can set `background` argument as well:

    from wand.color import Color
    from wand.image import Image

    with Color('red') as bg:
        with Image(width=200, height=100, background=bg) as img:
            img.save(filename='200x100-red.png')

Added in version 0.2.2: The `width`, `height`, and `background` parameters to `Image` constructor.

## Open a Pseudo Image

A pseudo image can refer to any of ImageMagick’s internal images that are accessible through coder protocols.

    from wand.image import Image

    with Image(width=100, height=100, pseudo='plasma:') as img:
        img.save(filename='100x100-plasma.png')

Common Pseudo images

- `'canvas:COLOR'`, or `'xc:COLOR'`, where COLOR is any valid color value string.

- `'caption:TEXT'`, where TEXT is a string message.

- `'gradient:START-END'`, generates a blended gradient between two colors, where both START and END are color value strings.

- `'hald:'`, creates a Higher And Lower Dimension matrix table.

- `'inline:VALUE'`, where VALUE is a data-url / base64 string value.

- `'label:TEXT'`, where TEXT is a string message.

- `'pattern:LABEL'`, generates a repeating pattern, where LABEL is the pattern name. See Built-in Patterns

- `'plasma:'`, generates a plasma fractal image.

- `'radial-gradient:'`, similar to gradient:, but generates a gradual blend from center of the image.

- `'tile:FILENAME'`, generates a repeating tile effect from a given images, where FILENAME is the path of a source image.

A list of all pseudo images can be found at https://imagemagick.org/script/formats.php#pseudo

Added in version 0.5.0: The `pseudo` parameter was added to the `Image` constructor.

## Read Modifiers

Opening an image with the filename property allows for ImageMagick’s Read Modifiers to be processed.

Single, or groups of, frames can be read without decoding all data. This can be useful to quick load the first page in a PDF:

    with Image(filename='document.pdf[0]') as first_page:
        pass

Or a range of frames:

    with Image(filename='animation.gif[0-11]') as first_dozen:
        pass

Or specific frames:

    with Image(filename='animation.gif[0,2]') as first_and_third:
        pass

You can also use `[WxH]` format to resize the input image during read:

    with Image(filename='logo.png[400x300]') as four_three_aspect:
        pass

Cropping an image can be achieved by following the `[WxH+x+y]` modifier:

    with Image(filename='logo.png[100x100+50+75]') as sub_image:
        pass