Some image files contain metadata that you can read to determine features of the image. For example, a digital photograph might contain metadata that you can read to determine the make and model of the camera used to capture the image.
GDI+ stores an individual piece of metadata in a
PropertyItem structure. The
GdipGetAllPropertyItems method returns an array of
PropertyItem structures. Before you call
GdipGetAllPropertyItems, you must allocate a buffer large enough to receive that array. You can call the
GdipGetPropertySize function to get the size, in bytes, of the required buffer. The
GdipGetPropertySize function also gives you the number of properties (pieces of metadata) in the image.
The following example creates an
Image object based on a JPEG file. The code calls the
GdipGetAllPropertyItems function to obtain its property items (metadata).
C++
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT main()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// Create an Image object based on a JPEG file.
Image* image = new Image(L"FakePhoto.jpg");
// Find out how many property items are in the image, and find out the
// required size of the buffer that will receive those property items.
UINT totalBufferSize;
UINT numProperties;
image->GetPropertySize(&totalBufferSize, &numProperties);
// Allocate the buffer that will receive the property items.
PropertyItem* pAllItems = (PropertyItem*)malloc(totalBufferSize);
// Fill the buffer.
image->GetAllPropertyItems(totalBufferSize, numProperties, pAllItems);
// Print the id data member of each property item.
for(UINT j = 0; j < numProperties; ++j)
{
printf("%x\n", pAllItems[j].id);
}
free(pAllItems);
delete image;
GdiplusShutdown(gdiplusToken);
return 0;
}
PowerBASICNote: Since the PowerBASIC compilers don't allow the use of dynamic arrays as members of an structure, the example uses an string as a buffer and later extracts portions of it and assigns them to a variable dimensioned as a
PropertyItem structure.
#COMPILE EXE
#DIM ALL
#INCLUDE "GDIPLUS.INC"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hStatus AS LONG
LOCAL token AS DWORD
LOCAL StartupInput AS GdiplusStartupInput
LOCAL pImage AS DWORD
LOCAL strFileName AS STRING
LOCAL totalBufferSize AS DWORD
LOCAL numProperties AS DWORD
LOCAL i AS LONG
LOCAL x AS LONG
LOCAL buffer AS STRING
LOCAL propItem AS PropertyItem
' Initialize GDI+
StartupInput.GdiplusVersion = 1
hStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
IF hStatus THEN
PRINT "Error initializing GDI+"
EXIT FUNCTION
END IF
' // Create an Image object, and then clone it.
strFileName = UCODE$("climber.jpg")
hStatus = GdipLoadImageFromFile(STRPTR(strFileName), pImage)
' // Find out how many property items are in the image, and find out the
' // required size of the buffer that will receive those property items.
hStatus = GdipGetPropertySize(pImage, totalBufferSize, numProperties)
' // Use an string as the buffer.
buffer = SPACE$(totalBufferSize)
hStatus = GdipGetAllPropertyItems(pImage, totalBufferSize, numProperties, BYVAL STRPTR(buffer))
IF hStatus = %StatusOk THEN
FOR i = 1 TO numProperties
LSET propItem = MID$(buffer, SIZEOF(PropertyItem) * (i - 1) + 1, SIZEOF(PropertyItem))
PRINT "&H" & HEX$(propItem.id)
PRINT propItem.length
PRINT propItem.type
PRINT propItem.value
SELECT CASE propItem.type
CASE %PropertyTagTypeASCII
' It is an asciiz array
LOCAL pvAscii AS ASCIIZ PTR
pvAscii = propItem.value
PRINT @pvAscii
CASE %PropertyTagTypeShort
' It is an array of integers
LOCAL pvShort AS INTEGER PTR
pvShort = propItem.value
FOR x = 1 TO propItem.length \ 2 ' Divide the length by the size of an integer
PRINT @pvShort[x-1] " ";
NEXT
PRINT
CASE %PropertyTagTypeByte
LOCAL pvByte AS BYTE PTR
pvByte = propItem.value
FOR x = 1 TO propItem.length
PRINT @pvByte[x-1] " ";
NEXT
PRINT
CASE %PropertyTagTypeLong
' It is an array of integers
LOCAL pvLong AS LONG PTR
pvLong = propItem.value
FOR x = 1 TO propItem.length \ 4 ' Divide the length by the size of a long
PRINT @pvLong[x-1] " ";
NEXT
PRINT
END SELECT
NEXT
END IF
' Shutdown GDI+
GdiplusShutdown token
WAITKEY$
END FUNCTION
' ========================================================================================