• Welcome to Jose's Read Only Forum 2023.
 

GDI+: GdipGetAllPropertyItems

Started by José Roca, June 23, 2008, 02:36:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca



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;
}


PowerBASIC

Note: 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
' ========================================================================================


José Roca