Here is a GDImage 64-bit console application to read EXIF properties from file.
This one is provided altogether with zTrace64.dll (64-bit version), that is being used to display the data.
Here is the code:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <bitset>
using namespace std;
#pragma comment(lib, "..\\GDImage64.lib")
//#pragma comment(lib, "..\\GDImage32.lib")
#include "GDImage.h"
#define PropertyTagImageDescription 0x010E
#define PropertyTagTypeASCII 2
#define long_proc typedef long (__stdcall *zProc)
long zTrace (IN wstring sPtr) {
long nRet = 0;
static HMODULE hDll;
if (hDll == 0) {
if (sizeof(LONG_PTR) == 8) {
hDll = LoadLibrary(L"zTrace64"); }
else {
hDll = LoadLibrary(L"zTrace32");
}
}
if (hDll) {
long_proc (WCHAR*);
zProc hProc = (zProc) GetProcAddress(hDll, "zTrace");
if (hProc) { nRet = hProc((WCHAR*) sPtr.c_str()); }
}
return nRet;
}
wstring STRL$(IN long N) {
WCHAR longstr[33] = {0};
_ltow_s(N, longstr, 10);
return (WCHAR*) longstr;
}
wstring RIGHT$(IN wstring sBuf, IN long nRight) {
wstring sResult = L"";
LONG_PTR nLength = sBuf.length();
if (nLength) { sResult = sBuf.substr(nLength - nRight, nRight); }
return sResult;
}
wstring PropertyToString(IN long nProperty) {
wstring sItem;
switch (nProperty) {
case 0x8769: sItem = L"Exif IFD"; break;
case 0x8825: sItem = L"Gps IFD"; break;
case 0x00FE: sItem = L"New subfile type"; break;
case 0x00FF: sItem = L"Sub file type"; break;
case 0x0100: sItem = L"Image width"; break;
case 0x0101: sItem = L"Image height"; break;
case 0x0102: sItem = L"Bits per sample"; break;
case 0x0103: sItem = L"Compression"; break;
case 0x0106: sItem = L"Photo metric interp"; break;
case 0x0107: sItem = L"ThreshHolding"; break;
case 0x0108: sItem = L"Cell width"; break;
case 0x0109: sItem = L"Cell height"; break;
case 0x010A: sItem = L"Fill order"; break;
case 0x010D: sItem = L"Document name"; break;
case 0x010E: sItem = L"Image description"; break;
case 0x010F: sItem = L"Manufacturer"; break;
case 0x0110: sItem = L"Model"; break;
case 0x0111: sItem = L"Strip offsets"; break;
case 0x0112: sItem = L"Orientation"; break; // 1 - The 0th row is at the top of the visual image, and the 0th column is the visual left side.
// 2 - The 0th row is at the visual top of the image, and the 0th column is the visual right side.
// 3 - The 0th row is at the visual bottom of the image, and the 0th column is the visual right side.
// 4 - The 0th row is at the visual bottom of the image, and the 0th column is the visual left side.
// 5 - The 0th row is the visual left side of the image, and the 0th column is the visual top.
// 6 - The 0th row is the visual right side of the image, and the 0th column is the visual top.
// 7 - The 0th row is the visual right side of the image, and the 0th column is the visual bottom.
// 8 - The 0th row is the visual left side of the image, and the 0th column is the visual bottom.
case 0x0115: sItem = L"Samples per pixel"; break;
case 0x0116: sItem = L"Rows per strip"; break;
case 0x0117: sItem = L"Strip bytes count"; break;
case 0x0118: sItem = L"Minimum sample value"; break;
case 0x0119: sItem = L"Maximum sample value"; break;
case 0x011A: sItem = L"Horizontal resolution"; break;
case 0x011B: sItem = L"Vertical resolution"; break;
case 0x011C: sItem = L"Planar config"; break;
case 0x011D: sItem = L"Page name"; break;
case 0x011E: sItem = L"Horizontal position"; break;
case 0x011F: sItem = L"Vertical position"; break;
case 0x0120: sItem = L"Free offset"; break;
case 0x0121: sItem = L"Free byte counts"; break;
case 0x0122: sItem = L"Gray response unit"; break;
case 0x0123: sItem = L"Gray response curve"; break;
case 0x0124: sItem = L"T4 option"; break;
case 0x0125: sItem = L"T6 option"; break;
case 0x0128: sItem = L"Resolution unit (2 = inch, 3 = cm)"; break;
case 0x0129: sItem = L"Page number"; break;
case 0x012D: sItem = L"Transfer function"; break;
case 0x0131: sItem = L"Software used"; break;
case 0x0132: sItem = L"Date Time"; break;
case 0x013B: sItem = L"Artist"; break;
case 0x013C: sItem = L"Host Computer"; break;
case 0x013D: sItem = L"Predictor"; break;
case 0x013E: sItem = L"White point"; break;
case 0x013F: sItem = L"Primary chromaticities"; break;
case 0x0140: sItem = L"Color map"; break;
case 0x0141: sItem = L"Halftone hints"; break;
case 0x0142: sItem = L"Tile width"; break;
case 0x0143: sItem = L"Tile length"; break;
case 0x0144: sItem = L"Tile offset"; break;
case 0x0145: sItem = L"Tile byte counts"; break;
case 0x014C: sItem = L"Ink set"; break;
case 0x014D: sItem = L"Ink names"; break;
case 0x014E: sItem = L"Number of inks"; break;
case 0x0150: sItem = L"Dot range"; break;
case 0x0151: sItem = L"Target printer"; break;
case 0x0152: sItem = L"Extra samples"; break;
case 0x0153: sItem = L"Sample format"; break;
case 0x0154: sItem = L"S Min sample value"; break;
case 0x0155: sItem = L"S Max sample value"; break;
case 0x0156: sItem = L"Transfer range"; break;
case 0x0200: sItem = L"Jpeg proc"; break;
case 0x0201: sItem = L"Jpeg inter format"; break;
case 0x0202: sItem = L"Jpeg inter length"; break;
case 0x0203: sItem = L"Jpeg restart interval"; break;
case 0x0205: sItem = L"Jpeg lossless predictors"; break;
case 0x0206: sItem = L"Jpeg point transforms"; break;
case 0x0207: sItem = L"Jpeg Q tables"; break;
case 0x0208: sItem = L"Jpeg DC tables"; break;
case 0x0209: sItem = L"Jpeg AC tables"; break;
case 0x0211: sItem = L"Height Cb Cr coefficients"; break;
case 0x0212: sItem = L"Height Cb Cr subsampling"; break;
case 0x0213: sItem = L"Height Cb Cr positioning"; break;
case 0x0214: sItem = L"REF black white"; break;
case 0x8773: sItem = L"ICC profile"; break;
case 0x0301: sItem = L"Gamma"; break;
case 0x0302: sItem = L"ICC profile descriptor"; break;
case 0x0303: sItem = L"SRGB rendering intent"; break;
case 0x0320: sItem = L"Image title"; break;
case 0x8298: sItem = L"Copyright"; break;
case 0x5001: sItem = L"Width resolution unit"; break;
case 0x5002: sItem = L"Height resolution unit"; break;
case 0x5003: sItem = L"Resolution width length unit"; break;
case 0x5004: sItem = L"Resolution height length unit"; break;
case 0x5005: sItem = L"Print flags"; break;
case 0x5006: sItem = L"Print flags version"; break;
case 0x5007: sItem = L"Print flags crop"; break;
case 0x5008: sItem = L"Print flags bleed width"; break;
case 0x5009: sItem = L"Print flags bleed Width Scale"; break;
case 0x500A: sItem = L"Halftone LPI"; break;
case 0x500B: sItem = L"Halftone LPI unit"; break;
case 0x500C: sItem = L"Halftone degree"; break;
case 0x500D: sItem = L"Halftone shape"; break;
case 0x500E: sItem = L"Halftone misc"; break;
case 0x500F: sItem = L"Halftone screen"; break;
case 0x5010: sItem = L"Jpeg quality"; break;
case 0x5011: sItem = L"Grid size"; break;
case 0x5012: sItem = L"Thumbnail format"; break;
case 0x5013: sItem = L"Thumbnail width"; break;
case 0x5014: sItem = L"Thumbnail height"; break;
case 0x5015: sItem = L"Thumbnail color depth"; break;
case 0x5016: sItem = L"Thumbnail Planes"; break;
case 0x5017: sItem = L"Thumbnail raw bytes"; break;
case 0x5018: sItem = L"Thumbnail size"; break;
case 0x5019: sItem = L"Thumbnail compressed size"; break;
case 0x501A: sItem = L"Color transfer function"; break;
case 0x501B: sItem = L"Thumbnail data"; break;
case 0x5020: sItem = L"Thumbnail image width"; break;
case 0x5021: sItem = L"Thumbnail image height"; break;
case 0x5022: sItem = L"Thumbnail bits per sample"; break;
case 0x5023: sItem = L"Thumbnail compression"; break;
case 0x5024: sItem = L"Thumbnail photometric interp"; break;
case 0x5025: sItem = L"Thumbnail image description"; break;
case 0x5026: sItem = L"Thumbnail equip make"; break;
case 0x5027: sItem = L"Thumbnail equip model"; break;
case 0x5028: sItem = L"Thumbnail strip offsets"; break;
case 0x5029: sItem = L"Thumbnail orientation"; break;
case 0x502A: sItem = L"Thumbnail samples per pixel"; break;
case 0x502B: sItem = L"Thumbnail rows per strip"; break;
case 0x502C: sItem = L"Thumbnail strip bytes count"; break;
case 0x502D: sItem = L"Thumbnail width"; break;
case 0x502E: sItem = L"Thumbnail height"; break;
case 0x502F: sItem = L"Thumbnail planar config"; break;
case 0x5030: sItem = L"Thumbnail resolution unit"; break;
case 0x5031: sItem = L"Thumbnail transfer function"; break;
case 0x5032: sItem = L"Thumbnail software used"; break;
case 0x5033: sItem = L"Thumbnail date time"; break;
case 0x5034: sItem = L"Thumbnail artist"; break;
case 0x5035: sItem = L"Thumbnail white point"; break;
case 0x5036: sItem = L"Thumbnail primary chromaticities"; break;
case 0x5037: sItem = L"Thumbnail Y Cb Cr coefficients"; break;
case 0x5038: sItem = L"Thumbnail Y Cb Cr subsampling"; break;
case 0x5039: sItem = L"Thumbnail Y Cb Crp positioning"; break;
case 0x503A: sItem = L"Thumbnail ref black & white"; break;
case 0x503B: sItem = L"Thumbnail copyright"; break;
case 0x5090: sItem = L"Luminance table"; break;
case 0x5091: sItem = L"Chrominance table"; break;
case 0x5100: sItem = L"Frame delay"; break;
case 0x5101: sItem = L"Loop count"; break;
case 0x5102: sItem = L"Global palette"; break;
case 0x5103: sItem = L"Index background"; break;
case 0x5104: sItem = L"Index transparent"; break;
case 0x5110: sItem = L"Pixel unit"; break;
case 0x5111: sItem = L"Horizontal pixel per unit"; break;
case 0x5112: sItem = L"Vertical pixel per unit"; break;
case 0x5113: sItem = L"Palette histogram"; break;
case 0x829A: sItem = L"Exposure time in seconds"; break;
case 0x829D: sItem = L"F Number"; break;
case 0x8822: sItem = L"Class of program used for exposure"; break;
case 0x8824: sItem = L"Spectral Sensitivity of each channel"; break;
case 0x8827: sItem = L"ISO Speed"; break;
case 0x8828: sItem = L"Opto-Electronic Conversion Function"; break;
case 0x9000: sItem = L"EXIF Version number"; break;
case 0x9003: sItem = L"Date + time of original"; break;
case 0x9004: sItem = L"Date + time of digitized"; break;
case 0x9101: sItem = L"Configuration of components"; break;
case 0x9102: sItem = L"Compression in bits per pixel"; break;
case 0x9201: sItem = L"Shutter speed, in APEX unit"; break;
case 0x9202: sItem = L"Lens aperture, in APEX unit"; break;
case 0x9203: sItem = L"Brightness, in APEX unit"; break;
case 0x9204: sItem = L"Exposure bias, unit is APEX"; break;
case 0x9205: sItem = L"Smallest F number of lens, in APEX"; break;
case 0x9206: sItem = L"Distance to subject, in meters"; break;
case 0x9207: sItem = L"Metering Mode"; break; // 0 - unknown,
// 1 - Average,
// 2 - CenterWeightedAverage,
// 3 - Spot,
// 4 - MultiSpot,
// 5 - Pattern,
// 6 - Partial,
// 7 to 254 - reserved,
// 255 - other.
case 0x9208: sItem = L"Light Source"; break;
case 0x9209: sItem = L"Strobe light (flash) source data"; break;
case 0x920A: sItem = L"Focal length, in mm"; break;
case 0x9214: sItem = L"Location and area of the main subject in the overall scene"; break;
case 0x927C: sItem = L"Manufacturer note"; break;
case 0x9286: sItem = L"Comments from user"; break;
case 0x9290: sItem = L"Exif DT Subsec"; break;
case 0x9291: sItem = L"Exif DT Orig SS"; break;
case 0x9292: sItem = L"Exif DT Dig SS"; break;
case 0xA000: sItem = L"Version of FlashPix"; break;
case 0xA001: sItem = L"Color space information"; break;
case 0xA002:
case 0x1001: sItem = L"Width in pixels"; break;
case 0xA003:
case 0x1002: sItem = L"Height in pixels"; break;
case 0xA004: sItem = L"Related WAV (8.3) sound file name"; break;
case 0xA005: sItem = L"Exif Interop"; break;
case 0xA20B: sItem = L"Strobe energy during image capture"; break;
case 0xA20C: sItem = L"Input device spatial frequency"; break;
case 0xA20E: sItem = L"Horizontal focal resolution (pixels/unit)"; break;
case 0xA20F: sItem = L"Vertical focal resolution (pixels/unit)"; break;
case 0xA210: sItem = L"Unit used for horizontal and vertical focal plane resolution"; break;
case 0xA214: sItem = L"Location of the main subject"; break;
case 0xA215: sItem = L"Exposure index of input device"; break;
case 0xA217: sItem = L"Image sensor type on input device"; break;
case 0xA300: sItem = L"Image source"; break;
case 0xA301: sItem = L"Type of scene"; break;
case 0xA302: sItem = L"Color filter array geometric pattern"; break;
case 0xA401: sItem = L"Special processing on image data"; break;
case 0xA402: sItem = L"Exposure mode"; break;
case 0xA403: sItem = L"White balance"; break;
case 0xA404: sItem = L"Digital zoom ratio"; break;
case 0xA405: sItem = L"Equivalent focal length in 35 mm film"; break;
case 0xA406: sItem = L"Type of scene that was shot"; break;
case 0xA407: sItem = L"Gain"; break;
case 0xA408: sItem = L"Contrast"; break;
case 0xA409: sItem = L"Saturation"; break;
case 0xA40A: sItem = L"Sharpness"; break;
case 0xA40B: sItem = L"Information on the picture-taking conditions"; break;
case 0xA40C: sItem = L"Distance to the subject"; break;
case 0xA420: sItem = L"Unique image ID"; break;
case 0x0000: sItem = L"Gps version"; break;
case 0x0001: sItem = L"Gps latitude ref"; break;
case 0x0002: sItem = L"Gps latitude"; break;
case 0x0003: sItem = L"Gps longitude ref"; break;
case 0x0004: sItem = L"Gps longitude"; break;
case 0x0005: sItem = L"Gps altitude ref"; break;
case 0x0006: sItem = L"Gps altitude"; break;
case 0x0007: sItem = L"Gps time"; break;
case 0x0008: sItem = L"Gps satellites"; break;
case 0x0009: sItem = L"Gps status"; break;
case 0x000A: sItem = L"Gps measure mode"; break;
case 0x000B: sItem = L"Gps dop"; break;
case 0x000C: sItem = L"Gps speed ref"; break;
case 0x000D: sItem = L"Gps speed"; break;
case 0x000E: sItem = L"Gps track ref"; break;
case 0x000F: sItem = L"Gps track"; break;
case 0x0010: sItem = L"Gps Img Dir ref"; break;
case 0x0011: sItem = L"Gps Img Dir"; break;
case 0x0012: sItem = L"Gps map datum"; break;
case 0x0013: sItem = L"Gps Dest Lat ref"; break;
case 0x0014: sItem = L"Gps Dest Lat"; break;
case 0x0015: sItem = L"Gps Dest Long ref"; break;
case 0x0016: sItem = L"Gps Dest Long"; break;
case 0x0017: sItem = L"Gps Dest Bear ref"; break;
case 0x0018: sItem = L"Gps Dest Bear"; break;
case 0x0019: sItem = L"Gps Dest Dist ref"; break;
case 0x001A: sItem = L"Gps Dest Dist"; break;
case 0x001B: sItem = L"Gps processing method"; break;
case 0x001C: sItem = L"Gps area information"; break;
case 0x001D: sItem = L"Gps date"; break;
case 0x001E: sItem = L"Gps differential"; break;
default:
sItem = L"Unknown property"; break;
}
sItem += L": ";
return sItem;
}
int _tmain(int argc, _TCHAR* argv[]) {
//LoadLibrary (L"GDIMAGE");
wstring sMsg, sImgName, sProperty, sItem;
WCHAR PathName[MAX_PATH] = {0}; WCHAR FilName[MAX_PATH] = {0};
zSplitN(zExeName(), &PathName[0], &FilName[0]);
sImgName = PathName; sImgName += L"Annecy.jpg";
long numOfProperty = 0, imgW = 0, imgH = 0;
LONG_PTR pImage = zLoadImageFromFile((WCHAR*) sImgName.c_str(), imgW, imgH, 0);
if (pImage) {
numOfProperty = ZI_GetImageInfoCount(pImage);
PROPID* propIDs = new PROPID[numOfProperty];
if (numOfProperty) {
if (ZI_GetImageInfoList(pImage, numOfProperty, propIDs) == 0) {
wstring sProperty;
for (long K = 0; K < numOfProperty; ++K) {
//wcout << K << L" " << (WCHAR*) PropertyToString(propIDs[K]).c_str() << (WCHAR*) ZI_GetImageInfoString(pImage, propIDs[K]).c_str() << endl;
sProperty = RIGHT$(L"000" + STRL$(K + 1), 3); sProperty += L" - "; sProperty += PropertyToString(propIDs[K]); sProperty += ZI_GetImageInfoString(pImage, propIDs[K]);
zTrace((WCHAR*) sProperty.c_str());
}
}
}
delete [] propIDs;
}
LONG_PTR pNewImage = zCloneImage(pImage);
if (pNewImage) {
sImgName = PathName; sImgName += L"Annecy_modified.jpg";
wstring sTitle = L"This is the title of the new clone image";
if (ZI_SetImageInfoProperty(pNewImage, PropertyTagImageDescription, (long) sTitle.length() + 1, PropertyTagTypeASCII, (WCHAR*) sTitle.c_str()) == 0 ) {
sMsg = L"\n\nThe name of the clone image is:\n";
sMsg += sImgName;
sMsg += L"\n\nIts new title is: \"";
sMsg += sTitle;
sMsg += L"\"";
}
zSaveImageToFile ((WCHAR*) sImgName.c_str(), pNewImage, 0);
// Cleanup the clone
ZI_DeleteImageObject(pNewImage);
}
// Cleanup original image.
ZI_DeleteImageObject(pImage);
wstring sReport = L"This image has "; sReport += STRL$(numOfProperty);
sReport += L" TAG properties"; sReport += sMsg;
wstring sCaption = L"GDImage "; sCaption += (WCHAR*) ZI_Version();
MessageBox(0, (WCHAR*) sReport.c_str(), (WCHAR*) sCaption.c_str(), MB_OK);
return 0;
}
You can download the VS2010 64-bit project here. (http://www.zapsolution.com/preview/Exif64.zip)