Image class

The base class of Bitmap and Metafile: a picture loaded from a file or a stream, with its size, resolution, pixel format and properties.

An Image holds either raster data or a recorded sequence of drawing commands. Bitmap and Metafile inherit every member described here and add the members that work on one kind of picture. A program creates an Image directly to load a file whose kind it does not know, and uses Type to find out which kind it got. The class mirrors the GDI+ Image class.

Note 0.9.45.0

A project that references the VB package (every default project does) also has a VB control class named Image. A bare Image in a declaration means the VB class, so write GdiPlus.Image for the class and for the function that creates it, as the samples on this page do. Bitmap and Metafile have no such clash.

Creating

Syntax: img = GdiPlus.Image( filename [ , useEmbeddedColorManagement ] )

Syntax: img = New GdiPlus.Image( filename [ , useEmbeddedColorManagement ] )

Syntax: img = GdiPlus.Image( stream [ , useEmbeddedColorManagement ] )

Syntax: img = GdiPlus.FromFile( filename [ , useEmbeddedColorManagement ] )

filename
required A String naming an image file. GDI+ decodes the formats that ImageCodec lists, and metafiles. The file stays open until the Image is released.
stream
required An IStream to read the picture from.
useEmbeddedColorManagement
optional A Boolean. True applies the colour profile stored in the file. The default is False.

The three forms with the same name are one thing: the function creates the object with the same arguments as New. FromFile is another name for the function. A constructor that fails creates an unusable object whose LastResult tells why. Loading a missing file gives OutOfMemory, which is how GDI+ reports a file it cannot open.

An Image that holds a bitmap is not a Bitmap: it has no pixel access. To read or change pixels, load the file with Bitmap instead.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(16!, 8!)
Dim g As Graphics = Graphics(bmp)
g.Clear(Color(255, 200, 100, 50))

Dim dir As String = Environ$("TEMP") & "\tbdocs-gdiplus-image"
ImagePageSaver.MakeDir dir
Dim path As String = dir & "\sample.png"
Debug.Print ImagePageSaver.SavePng(bmp, path)

Dim img As GdiPlus.Image = GdiPlus.Image(path)
Debug.Print img.LastResult & " " & img.Width & " " & img.Height & " " & img.Type

Dim missing As GdiPlus.Image = GdiPlus.Image(dir & "\no-such-file.png")
Debug.Print missing.LastResult
' Output:
' 0
' 0 16 8 1
' 3

Clone

Syntax: copy = img.Clone( )

Returns a new Image that holds a copy of the picture. The copy is an Image, even when the original is a Bitmap or a Metafile.

Note 0.9.45.0

Bitmap and Metafile declare their own Clone, and on a Bitmap the no-argument form is not available: the call does not compile. To copy a whole Bitmap, use Bitmap.Clone with the full rectangle.

Saving

Save writes the picture to a file or a stream with one of the encoders listed by ImageCodec. clsidEncoder is the class ID of the encoder: ImageCodecPNG, ImageCodecJPG and the others are functions that return it.

Save

Syntax: status = img.Save( filename, clsidEncoder, encoderParams( ) )

Syntax: status = img.Save( stream, clsidEncoder, encoderParams( ) )

filename
required A String naming the file to write. An existing file is replaced.
stream
required An IStream to write to.
clsidEncoder
required The class ID of the encoder, which also selects the file format.
encoderParams
required An array of GpEncoderParameter. The call expects its lower bound to be 0, and element 0 to be a dummy that is not filled in; the parameters follow from element 1. Any other lower bound returns InvalidParameter.

SaveAdd

Syntax: status = img.SaveAdd( encoderParams( ) )

Syntax: status = img.SaveAddImage( newImage, encoderParams( ) )

Adds a frame to a file that an earlier Save started with the EncoderSaveFlag parameter set to multi-frame. SaveAdd adds the frame of the picture itself; SaveAddImage adds the frame of newImage, an Image. Both take encoderParams as Save does, and are subject to the same warning.

Size and format

Type

Syntax: t = img.Type

Returns a GpImageType: ImageTypeBitmap for raster data and ImageTypeMetafile for a recording. The property is read-only.

Width, Height, Size

Syntax: w = img.Width

Syntax: h = img.Height

Syntax: s = img.Size

Width and Height return the size in pixels as a Long. Size returns both in a GpSize. For a metafile the numbers are the size of the bounds in device units.

Dimension

Syntax: d = img.Dimension

Returns the width and height as a GpSizeF in the unit of the picture, which for a bitmap is the pixel and for a metafile depends on its frame.

Bounds

Syntax: r = img.Bounds( srcUnit )

srcUnit
required A GpUnit giving the unit of the returned rectangle.

Returns a GpRectF whose upper left corner is (0, 0) for a bitmap and whose size is the size of the picture in srcUnit.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(8!, 6!)
Debug.Print bmp.Type & " " & bmp.Width & " " & bmp.Height
Debug.Print bmp.Size.Width & " " & bmp.Size.Height
Debug.Print bmp.Dimension.Width & " " & bmp.Dimension.Height

Dim b As GpRectF = bmp.Bounds(UnitPixel)
Debug.Print b.X & " " & b.Y & " " & b.Width & " " & b.Height
' Output:
' 1 8 6
' 8 6
' 8 6
' 0 0 8 6

HorizontalResolution, VerticalResolution

Syntax: dpi = img.HorizontalResolution

Syntax: dpi = img.VerticalResolution

Return the resolution in dots per inch as a Single. A new bitmap takes the resolution of the screen, so the number differs between machines. Set it with Bitmap.SetResolution.

PixelFormat

Syntax: fmt = img.PixelFormat

Returns the PixelFormat of the picture. A bitmap created without a format has PixelFormat32bppARGB.

Flags

Syntax: flags = img.Flags

Returns a combination of ImageFlags values as a Long: whether the picture scales, has alpha or translucent pixels, its colour space and whether its resolution and size come from the file.

RawFormat

Syntax: id = img.RawFormat

Returns the class ID of the file format the picture was loaded from, as a UUID. Compare it with the values that the format functions return, such as ImageFormatPNG. A picture created in memory has ImageFormatMemoryBMP.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(4!, 4!)
Debug.Print Hex$(bmp.PixelFormat)
Debug.Print Hex$(bmp.Flags)
Debug.Print bmp.RawFormat.Data1 = ImageFormatMemoryBMP().Data1
' Output:
' 26200A
' 2
' True

Palette

PaletteSize

Syntax: n = img.PaletteSize

Returns the size in bytes of the colour palette of the picture, which is 0 or a small header for a picture without a palette and 1032 for a bitmap in the PixelFormat8bppIndexed format.

Palette

Syntax: pal = img.Palette

Syntax: img.Palette = pal

The getter is meant to return the palette as an array of ColorPalette, and the setter to take one.

Thumbnails

GetThumbnail

Syntax: thumb = img.GetThumbnail( thumbSize [ , callback [ , callbackData ] ] )

Syntax: thumb = img.GetThumbnail( thumbWidth, thumbHeight [ , callback [ , callbackData ] ] )

thumbSize
required A GpSize with the size of the thumbnail in pixels.
thumbWidth, thumbHeight
required Long values for the same size.
callback
optional A callback that GDI+ can call to ask whether it should stop. Omit it.
callbackData
optional A pointer passed to callback. The default is 0.

Returns a new Image of the requested size, or Nothing when the call fails. The thumbnail is the embedded one when the file has one, and a scaled copy of the picture otherwise.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(40!, 20!)
Dim thumb As GdiPlus.Image = bmp.GetThumbnail(10, 5)
Debug.Print bmp.LastResult & " " & thumb.Width & " " & thumb.Height
' Output:
' 0 10 5

Frames

An image file can hold several frames, such as the pages of a TIFF or the pictures of an animated GIF. Frames are grouped in dimensions; the identifiers are the functions FrameDimensionTime, FrameDimensionPage and FrameDimensionResolution.

FrameDimensionsCount

Syntax: n = img.FrameDimensionsCount

Returns the number of frame dimensions the picture has. A bitmap created in memory has one: the page dimension.

GetFrameDimensionsList

Syntax: ids = img.GetFrameDimensionsList( )

Returns the class IDs of the frame dimensions as an array of UUID that starts at 1.

FrameCount

Syntax: n = img.FrameCount( dimensionID )

dimensionID
required The class ID of a frame dimension, such as FrameDimensionPage( ).

Returns the number of frames in that dimension.

SelectActiveFrame

Syntax: status = img.SelectActiveFrame( dimensionID, frameIndex )

dimensionID
required The class ID of a frame dimension.
frameIndex
required The index of the frame to select, counted from 0.

Makes the frame the one that drawing and the size properties use.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(4!, 4!)
Debug.Print bmp.FrameDimensionsCount
Debug.Print bmp.FrameCount(FrameDimensionPage())
Debug.Print bmp.GetFrameDimensionsList()(1).Data1 = FrameDimensionPage().Data1
Debug.Print bmp.SelectActiveFrame(FrameDimensionPage(), 0)
' Output:
' 1
' 1
' True
' 0

RotateFlip

Syntax: status = img.RotateFlip( rotateFlipType )

rotateFlipType
required A RotateFlipType giving a rotation, a flip, or both. The picture is rotated first.

Rotates and flips the picture in place. A rotation is clockwise. After a rotation by 90 or 270 degrees the width and height are exchanged.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(4!, 3!)
bmp.Pixel(0, 0) = Color(255, 255, 0, 0)       ' upper left corner
bmp.RotateFlip Rotate90FlipNone
Debug.Print bmp.Width & " " & bmp.Height
Debug.Print Hex$(bmp.Pixel(2, 0).argb)        ' the red pixel is now at the upper right
bmp.RotateFlip Rotate270FlipNone
bmp.RotateFlip RotateNoneFlipX
Debug.Print Hex$(bmp.Pixel(3, 0).argb)        ' flipped across the vertical axis
' Output:
' 3 4
' FFFF0000
' FFFF0000

Properties of a file

An image file can hold named properties: the camera model of a photograph, the time it was taken, the delay of a GIF frame. Each has a numeric ID, and the PropertyTag... constants of the package name the IDs of the common ones. A property is a GpPropertyItem.

PropertyCount

Syntax: n = img.PropertyCount

Returns the number of properties the picture has.

PropertyIdList

Syntax: ids = img.PropertyIdList

Returns the IDs of the properties as an array of Long that starts at 1.

PropertyItem

Syntax: items = img.PropertyItem( propId )

Syntax: img.PropertyItem = item

The getter returns the property with the ID propId as an array of GpPropertyItem that holds one element, at index 1. The setter takes one GpPropertyItem and sets that property on the picture, adding it when it is not there. Its Id, type, length and the address of its value must be filled in.

RemovePropertyItem

Syntax: status = img.RemovePropertyItem( propId )

Removes the property with that ID.

GetAllPropertyItems

Syntax: items = img.GetAllPropertyItems( )

Returns all properties as an array of GpPropertyItem. See the warning under PropertyItem.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(4!, 4!)
Dim text() As Byte = StrConv("A test picture" & vbNullChar, vbFromUnicode)

Dim item As GpPropertyItem
item.Id = PropertyTagImageDescription
item._type = PropertyTagTypeASCII
item._length = UBound(text) + 1
item._address = VarPtr(text(0))
bmp.PropertyItem = item
Debug.Print bmp.LastResult & " " & bmp.PropertyCount
Debug.Print Hex$(bmp.PropertyIdList()(1))

Debug.Print bmp.RemovePropertyItem(PropertyTagImageDescription)
Debug.Print bmp.PropertyCount
' Output:
' 0 1
' 10E
' 0
' 0

GetEncoderParameterList

Syntax: params = img.GetEncoderParameterList( clsidEncoder )

Returns the parameters that the encoder with the class ID clsidEncoder accepts for this picture, as an array of GpEncoderParameter.

Items of image data

Some formats store data beside the pixels. FindFirstItem, FindNextItem and GetItemData enumerate and read it, with a GpImageItemData in an array of one element. These members need GDI+ 1.1 and Windows 7 or later, and only the codecs that provide such data return any. The array is built as for PropertyItem, so its element cannot be read.

FindFirstItem

Syntax: item = img.FindFirstItem( )

FindNextItem

Syntax: item = img.FindNextItem( )

GetItemData

Syntax: status = img.GetItemData( item( ) )

FindFirstItem and FindNextItem return the first and the following item as an array of one GpImageItemData. GetItemData reads the data of the item in the array that is passed to it.

SetAbort

Syntax: status = img.SetAbort( pIAbort )

GDI+ declares this function, but does not implement it in versions 1.0 and 1.1: it does nothing useful. The argument is a GdiPlusAbort object.

Example

The example makes a small picture, rotates and flips it, and reads the results back.

Dim user As GdiPlusUser = GdiPlusUser()

Dim bmp As Bitmap = Bitmap(6!, 2!)
Dim g As Graphics = Graphics(bmp)
g.Clear(Color(255, 255, 255, 255))
bmp.Pixel(0, 0) = Color(255, 0, 0, 255)

Dim copy As GdiPlus.Image = bmp
Debug.Print copy.Width & "x" & copy.Height & " " & copy.Type

bmp.RotateFlip Rotate180FlipNone
Debug.Print Hex$(bmp.Pixel(5, 1).argb)
' Output:
' 6x2 1
' FF0000FF

See Also