
Discovering the Property Items present in an image.Image file formats will always provide pertinent data about the size and resolution of an image. These are fundamental to reading and decoding the picture. In some cases, such as the pixel bit depth of GIF files, certain properties are implied. In other cases, explicit metadata detailing the pixel format, the time that the image was created and other useful information is encapsulated in the file. GDI+ enables you to read this metadata from the image in the form of a collection of PropertyItem objects. There are many possible PropertyItem identifiers which are coded internally as a standard identification number, the length of the data, a value type and a value to associate with the identification. The Image class contains the PropertyItems collection which can be iterated quite simply to obtain each of the property items in turn. To extract the useful information, the meaning of the tag, the type of value contained and the actual values can be displayed or analysed by your code. The program in listing 1 performs the function of reading all the tags in an image, ascertaining which image property tags are present and decoding them line by line in a text list. A detailed listing of the property item tags may be found in the MSDN help that comes with Visual Studio or online here Listing 1: using
System; using
System.Text; using
System.Drawing; using
System.Drawing.Imaging; using
System.Collections; using
System.ComponentModel; using
System.Windows.Forms; using
System.Data; namespace
ImageAnalyser { ///
<summary> ///
Summary description for Form1. ///
</summary> public class
Form1 : System.Windows.Forms.Form { private
System.Windows.Forms.TextBox textBox1; private
System.Windows.Forms.Button button1; private
System.Windows.Forms.Button button2; ///
<summary> ///
Required designer variable. ///
</summary> private
System.ComponentModel.Container components = null; public Form1() { // // Required
for Windows Form Designer support // InitializeComponent(); // // TODO:
Add any constructor code after InitializeComponent call // } ///
<summary> ///
Clean up any resources being used. ///
</summary> protected override
void Dispose( bool
disposing ) { if(
disposing ) { if
(components != null) { components.Dispose(); } } base.Dispose(
disposing ); }
#region Windows Form Designer generated code ///
<summary> ///
Required method for Designer support - do not modify ///
the contents of this method with the code editor. ///
</summary> private void InitializeComponent() { this.textBox1
= new System.Windows.Forms.TextBox(); this.button1
= new System.Windows.Forms.Button(); this.button2
= new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Anchor
= ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom) |
System.Windows.Forms.AnchorStyles.Left) |
System.Windows.Forms.AnchorStyles.Right))); this.textBox1.Font
= new System.Drawing.Font("Courier
New", 8.25F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.textBox1.Location
= new System.Drawing.Point(8, 16); this.textBox1.Multiline
= true; this.textBox1.Name
= "textBox1"; this.textBox1.ScrollBars
= System.Windows.Forms.ScrollBars.Both; this.textBox1.Size
= new System.Drawing.Size(332, 311); this.textBox1.TabIndex
= 0; this.textBox1.Text
= ""; // // button1 // this.button1.Anchor
= ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Right))); this.button1.Location
= new System.Drawing.Point(360, 32); this.button1.Name
= "button1"; this.button1.Size
= new System.Drawing.Size(64, 24); this.button1.TabIndex
= 1; this.button1.Text
= "Load"; this.button1.Click
+= new System.EventHandler(this.button1_Click); // // button2 // this.button2.Anchor
= ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Right))); this.button2.Location
= new System.Drawing.Point(352, 224); this.button2.Name
= "button2"; this.button2.TabIndex
= 2; this.button2.Text
= "Quit"; this.button2.Click
+= new System.EventHandler(this.button2_Click); // // Form1 // this.AutoScaleBaseSize
= new System.Drawing.Size(5, 13); this.ClientSize
= new System.Drawing.Size(440, 344); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.FormBorderStyle
= System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.Name
= "Form1"; this.Text
= "Form1"; this.ResumeLayout(false); }
#endregion ///
<summary> ///
The main entry point for the application. ///
</summary> [STAThread] static void
Main() { Application.Run(new
Form1()); } private void button2_Click(object sender,
System.EventArgs e) { Application.Exit(); } string
DumpValues(byte[] v) { StringBuilder sb=new
StringBuilder(); int
index1=0; int
index2=0; for(index1=0;
index1<v.Length; index1+=16) { sb.Append("\t"); for(index2=0;
index2<16; index2++) { if(index1+index2<v.Length) sb.Append(v[index1+index2].ToString("X02")+"
"); else sb.Append("
"); } sb.Append("\t"); for(index2=0;
index2<16; index2++) { if(index1+index2<v.Length) { char
c=(char)v[index1+index2]; if(c<0x20)
sb.Append("."); else
sb.Append(c); } } sb.Append("\r\n"); } return
sb.ToString(); } private void button1_Click(object sender,
System.EventArgs e) { OpenFileDialog dlg=new
OpenFileDialog(); dlg.Filter="Image files|*.tif;*.jpg;*.jpeg;*.bmp;*.tiff;*.gif"; if(dlg.ShowDialog()==DialogResult.OK) { Image img =
Image.FromFile(dlg.FileName); this.textBox1.Text=""; StringBuilder sb=new
StringBuilder(); sb.Append(string.Format( "Image:
{0}\r\n"+ "Width=
{1}, Height= {2}\r\n"+ "PixelFormat
= {3}\r\n"+ "Dumping
{4} property
items:",dlg.FileName,img.Width,img.Height,img.PixelFormat,img.PropertyItems.Length)); foreach(PropertyItem
i in img.PropertyItems) { string
s="UnknownTag"; switch(i.Id) { case
0x0000 :
s="PropertyTagGpsVer ";
break; case
0x0001 :
s="PropertyTagGpsLatitudeRef ";
break; case
0x0002 :
s="PropertyTagGpsLatitude ";
break; case
0x0003 :
s="PropertyTagGpsLongitudeRef
";
break; case
0x0004 :
s="PropertyTagGpsLongitude ";
break; case
0x0005 :
s="PropertyTagGpsAltitudeRef ";
break; case
0x0006 :
s="PropertyTagGpsAltitude ";
break; case
0x0007 :
s="PropertyTagGpsGpsTime ";
break; case
0x0008 :
s="PropertyTagGpsGpsSatellites ";
break; case
0x0009 :
s="PropertyTagGpsGpsStatus ";
break; case
0x000A :
s="PropertyTagGpsGpsMeasureMode ";
break; case
0x000B :
s="PropertyTagGpsGpsDop ";
break; case
0x000C :
s="PropertyTagGpsSpeedRef ";
break; case
0x000D :
s="PropertyTagGpsSpeed ";
break; case
0x000E :
s="PropertyTagGpsTrackRef ";
break; case
0x000F :
s="PropertyTagGpsTrack ";
break; case
0x0010 :
s="PropertyTagGpsImgDirRef ";
break; case
0x0011 :
s="PropertyTagGpsImgDir ";
break; case
0x0012 :
s="PropertyTagGpsMapDatum ";
break; case
0x0013 :
s="PropertyTagGpsDestLatRef ";
break; case
0x0014 :
s="PropertyTagGpsDestLat
";
break; case
0x0015 :
s="PropertyTagGpsDestLongRef ";
break; case
0x0016 :
s="PropertyTagGpsDestLong ";
break; case
0x0017 :
s="PropertyTagGpsDestBearRef ";
break; case
0x0018 :
s="PropertyTagGpsDestBear ";
break; case
0x0019 :
s="PropertyTagGpsDestDistRef "; break; case
0x001A :
s="PropertyTagGpsDestDist ";
break; case
0x00FE :
s="PropertyTagNewSubfileType ";
break; case
0x00FF :
s="PropertyTagSubfileType ";
break; case
0x0100 :
s="PropertyTagImageWidth ";
break; case
0x0101 :
s="PropertyTagImageHeight ";
break; case
0x0102 :
s="PropertyTagBitsPerSample ";
break; case
0x0103 :
s="PropertyTagCompression ";
break; case
0x0106 :
s="PropertyTagPhotometricInterp ";
break; case
0x0107 :
s="PropertyTagThreshHolding
";
break; case
0x0108 :
s="PropertyTagCellWidth ";
break; case
0x0109 :
s="PropertyTagCellHeight ";
break; case
0x010A :
s="PropertyTagFillOrder ";
break; case
0x010D :
s="PropertyTagDocumentName ";
break; case
0x010E :
s="PropertyTagImageDescription ";
break; case
0x010F :
s="PropertyTagEquipMake ";
break; case
0x0110 :
s="PropertyTagEquipModel ";
break; case
0x0111 :
s="PropertyTagStripOffsets "; break; case
0x0112 :
s="PropertyTagOrientation ";
break; case
0x0115 :
s="PropertyTagSamplesPerPixel ";
break; case
0x0116 :
s="PropertyTagRowsPerStrip ";
break; case
0x0117 :
s="PropertyTagStripBytesCount ";
break; case
0x0118 :
s="PropertyTagMinSampleValue ";
break; case
0x0119 :
s="PropertyTagMaxSampleValue ";
break; case
0x011A :
s="PropertyTagXResolution ";
break; case
0x011B :
s="PropertyTagYResolution ";
break; case
0x011C :
s="PropertyTagPlanarConfig ";
break; case
0x011D :
s="PropertyTagPageName ";
break; case
0x011E :
s="PropertyTagXPosition ";
break; case
0x011F :
s="PropertyTagYPosition ";
break; case
0x0120 :
s="PropertyTagFreeOffset ";
break; case
0x0121 :
s="PropertyTagFreeByteCounts ";
break; case
0x0122 :
s="PropertyTagGrayResponseUnit ";
break; case
0x0123 :
s="PropertyTagGrayResponseCurve ";
break; case
0x0124 :
s="PropertyTagT4Option ";
break; case
0x0125 :
s="PropertyTagT6Option ";
break; case
0x0128 :
s="PropertyTagResolutionUnit ";
break; case
0x0129 :
s="PropertyTagPageNumber ";
break; case
0x012D :
s="PropertyTagTransferFunction ";
break; case
0x0131 :
s="PropertyTagSoftwareUsed ";
break; case
0x0132 :
s="PropertyTagDateTime
";
break; case
0x013B :
s="PropertyTagArtist ";
break; case
0x013C :
s="PropertyTagHostComputer ";
break; case
0x013D :
s="PropertyTagPredictor ";
break; case
0x013E :
s="PropertyTagWhitePoint ";
break; case
0x013F :
s="PropertyTagPrimaryChromaticities ";
break; case
0x0140 :
s="PropertyTagColorMap ";
break; case
0x0141 :
s="PropertyTagHalftoneHints ";
break; case
0x0142 :
s="PropertyTagTileWidth "; break; case
0x0143 :
s="PropertyTagTileLength ";
break; case
0x0144 :
s="PropertyTagTileOffset ";
break; case
0x0145 :
s="PropertyTagTileByteCounts ";
break; case
0x014C :
s="PropertyTagInkSet ";
break; case
0x014D :
s="PropertyTagInkNames ";
break; case
0x014E :
s="PropertyTagNumberOfInks ";
break; case
0x0150 :
s="PropertyTagDotRange ";
break; case
0x0151 :
s="PropertyTagTargetPrinter ";
break; case
0x0152 :
s="PropertyTagExtraSamples ";
break; case
0x0153 :
s="PropertyTagSampleFormat ";
break; case
0x0154 :
s="PropertyTagSMinSampleValue ";
break; case
0x0155 :
s="PropertyTagSMaxSampleValue ";
break; case
0x0156 :
s="PropertyTagTransferRange ";
break; case
0x0200 :
s="PropertyTagJPEGProc ";
break; case
0x0201 :
s="PropertyTagJPEGInterFormat ";
break; case
0x0202 :
s="PropertyTagJPEGInterLength ";
break; case
0x0203 :
s="PropertyTagJPEGRestartInterval ";
break; case
0x0205 :
s="PropertyTagJPEGLosslessPredictors ";
break; case
0x0206 :
s="PropertyTagJPEGPointTransforms ";
break; case
0x0207 :
s="PropertyTagJPEGQTables ";
break; case
0x0208 :
s="PropertyTagJPEGDCTables ";
break; case
0x0209 :
s="PropertyTagJPEGACTables ";
break; case
0x0211 :
s="PropertyTagYCbCrCoefficients ";
break; case
0x0212 :
s="PropertyTagYCbCrSubsampling ";
break; case
0x0213 :
s="PropertyTagYCbCrPositioning "; break; case
0x0214 :
s="PropertyTagREFBlackWhite ";
break; case
0x0301 :
s="PropertyTagGamma ";
break; case
0x0302 :
s="PropertyTagICCProfileDescriptor ";
break; case
0x0303 :
s="PropertyTagSRGBRenderingIntent ";
break; case
0x0320 :
s="PropertyTagImageTitle ";
break; case
0x5001 :
s="PropertyTagResolutionXUnit ";
break; case
0x5002 :
s="PropertyTagResolutionYUnit ";
break; case
0x5003 :
s="PropertyTagResolutionXLengthUnit ";
break; case
0x5004 :
s="PropertyTagResolutionYLengthUnit ";
break; case
0x5005 :
s="PropertyTagPrintFlags ";
break; case
0x5006 :
s="PropertyTagPrintFlagsVersion ";
break; case
0x5007 :
s="PropertyTagPrintFlagsCrop ";
break; case
0x5008 :
s="PropertyTagPrintFlagsBleedWidth ";
break; case
0x5009 :
s="PropertyTagPrintFlagsBleedWidthScale ";
break; case
0x500A :
s="PropertyTagHalftoneLPI ";
break; case
0x500B :
s="PropertyTagHalftoneLPIUnit ";
break; case
0x500C :
s="PropertyTagHalftoneDegree ";
break; case
0x500D :
s="PropertyTagHalftoneShape ";
break; case
0x500E :
s="PropertyTagHalftoneMisc "; break; case
0x500F :
s="PropertyTagHalftoneScreen ";
break; case
0x5010 :
s="PropertyTagJPEGQuality ";
break; case
0x5011 :
s="PropertyTagGridSize ";
break; case
0x5012 :
s="PropertyTagThumbnailFormat ";
break; case
0x5013 :
s="PropertyTagThumbnailWidth ";
break; case
0x5014 :
s="PropertyTagThumbnailHeight ";
break; case
0x5015 :
s="PropertyTagThumbnailColorDepth ";
break; case
0x5016 :
s="PropertyTagThumbnailPlanes ";
break; case
0x5017 :
s="PropertyTagThumbnailRawBytes ";
break; case
0x5018 :
s="PropertyTagThumbnailSize ";
break; case
0x5019 :
s="PropertyTagThumbnailCompressedSize "; break; case
0x501A :
s="PropertyTagColorTransferFunction ";
break; case
0x501B :
s="PropertyTagThumbnailData ";
break; case
0x5020 :
s="PropertyTagThumbnailImageWidth ";
break; case
0x5021 :
s="PropertyTagThumbnailImageHeight ";
break; case
0x5022 :
s="PropertyTagThumbnailBitsPerSample ";
break; case
0x5023 :
s="PropertyTagThumbnailCompression ";
break; case
0x5024 :
s="PropertyTagThumbnailPhotometricInterp ";
break; case
0x5025 :
s="PropertyTagThumbnailImageDescription ";
break; case
0x5026 :
s="PropertyTagThumbnailEquipMake ";
break; case
0x5027 :
s="PropertyTagThumbnailEquipModel ";
break; case
0x5028 :
s="PropertyTagThumbnailStripOffsets ";
break; case
0x5029 :
s="PropertyTagThumbnailOrientation ";
break; case
0x502A :
s="PropertyTagThumbnailSamplesPerPixel ";
break; case
0x502B :
s="PropertyTagThumbnailRowsPerStrip ";
break; case
0x502C :
s="PropertyTagThumbnailStripBytesCount ";
break; case
0x502D :
s="PropertyTagThumbnailResolutionX ";
break; case
0x502E :
s="PropertyTagThumbnailResolutionY ";
break; case
0x502F :
s="PropertyTagThumbnailPlanarConfig ";
break; case
0x5030 :
s="PropertyTagThumbnailResolutionUnit ";
break; case
0x5031 :
s="PropertyTagThumbnailTransferFunction ";
break; case
0x5032 :
s="PropertyTagThumbnailSoftwareUsed
";
break; case
0x5033 :
s="PropertyTagThumbnailDateTime ";
break; case
0x5034 :
s="PropertyTagThumbnailArtist ";
break; case
0x5035 :
s="PropertyTagThumbnailWhitePoint ";
break; case
0x5036 :
s="PropertyTagThumbnailPrimaryChromaticities ";
break; case
0x5037 :
s="PropertyTagThumbnailYCbCrCoefficients ";
break; case
0x5038 :
s="PropertyTagThumbnailYCbCrSubsampling ";
break; case
0x5039 :
s="PropertyTagThumbnailYCbCrPositioning "; break; case
0x503A :
s="PropertyTagThumbnailRefBlackWhite ";
break; case
0x503B :
s="PropertyTagThumbnailCopyRight ";
break; case
0x5090 :
s="PropertyTagLuminanceTable ";
break; case
0x5091 :
s="PropertyTagChrominanceTable ";
break; case
0x5100 :
s="PropertyTagFrameDelay ";
break; case
0x5101 :
s="PropertyTagLoopCount ";
break; case
0x5102 :
s="PropertyTagGlobalPalette ";
break; case
0x5103 :
s="PropertyTagIndexBackground ";
break; case
0x5104 :
s="PropertyTagIndexTransparent ";
break; case
0x5110 :
s="PropertyTagPixelUnit ";
break; case
0x5111 :
s="PropertyTagPixelPerUnitX "; break; case
0x5112 :
s="PropertyTagPixelPerUnitY ";
break; case
0x5113 :
s="PropertyTagPaletteHistogram ";
break; case
0x8298 :
s="PropertyTagCopyright ";
break; case
0x829A :
s="PropertyTagExifExposureTime ";
break; case
0x829D : s="PropertyTagExifFNumber
"; break; case
0x8769 : s="PropertyTagExifIFD
"; break; case
0x8773 : s="PropertyTagICCProfile
"; break; case
0x8822 : s="PropertyTagExifExposureProg
"; break; case
0x8824 : s="PropertyTagExifSpectralSense
"; break; case
0x8825 : s="PropertyTagGpsIFD
"; break; case
0x8827 : s="PropertyTagExifISOSpeed
"; break; case
0x8828 : s="PropertyTagExifOECF
"; break; case
0x9000 : s="PropertyTagExifVer
"; break; case
0x9003 : s="PropertyTagExifDTOrig
"; break; case
0x9004 : s="PropertyTagExifDTDigitized
"; break; case
0x9101 : s="PropertyTagExifCompConfig
"; break; case
0x9102 : s="PropertyTagExifCompBPP
"; break; case
0x9201 : s="PropertyTagExifShutterSpeed
"; break; case
0x9202 : s="PropertyTagExifAperture
"; break; case
0x9203 : s="PropertyTagExifBrightness
"; break; case
0x9204 : s="PropertyTagExifExposureBias
"; break; case
0x9205 : s="PropertyTagExifMaxAperture
"; break; case
0x9206 : s="PropertyTagExifSubjectDist
"; break; case
0x9207 : s="PropertyTagExifMeteringMode
"; break; case
0x9208 : s="PropertyTagExifLightSource
"; break; case
0x9209 : s="PropertyTagExifFlash
"; break; case
0x920A : s="PropertyTagExifFocalLength
"; break; case
0x927C : s="PropertyTagExifMakerNote
"; break; case
0x9286 : s="PropertyTagExifUserComment
"; break; case
0x9290 : s="PropertyTagExifDTSubsec
"; break; case
0x9291 : s="PropertyTagExifDTOrigSS
"; break; case
0x9292 : s="PropertyTagExifDTDigSS
"; break; case
0xA000 : s="PropertyTagExifFPXVer
"; break; case
0xA001 : s="PropertyTagExifColorSpace
"; break; case
0xA002 : s="PropertyTagExifPixXDim
"; break; case
0xA003 : s="PropertyTagExifPixYDim
"; break; case
0xA004 : s="PropertyTagExifRelatedWav
"; break; case
0xA005 : s="PropertyTagExifInterop
"; break; case
0xA20B : s="PropertyTagExifFlashEnergy
"; break; case
0xA20C : s="PropertyTagExifSpatialFR
"; break; case
0xA20E : s="PropertyTagExifFocalXRes
"; break; case
0xA20F : s="PropertyTagExifFocalYRes
"; break; case
0xA210 : s="PropertyTagExifFocalResUnit
"; break; case
0xA214 : s="PropertyTagExifSubjectLoc
"; break; case
0xA215 : s="PropertyTagExifExposureIndex
"; break; case
0xA217 : s="PropertyTagExifSensingMethod
"; break; case
0xA300 : s="PropertyTagExifFileSource
"; break; case
0xA301 : s="PropertyTagExifSceneType
"; break; case
0xA302 : s="PropertyTagExifCfaPattern
"; break; } sb.Append(s+"\r\n"); string
t="UnknownType"; switch(i.Type) { case
1: t="PropertyTagTypeByte"; break; case
2: t="PropertyTagTypeASCII"; break; case
3: t="PropertyTagTypeShort"; break; case
4: t="PropertyTagTypeLong"; break; case
5: t="PropertyTagTypeRational"; break; case
7: t="PropertyTagTypeUndefined"; break; case
9: t="PropertyTagTypeSLONG"; break; case
10: t="PropertyTagTypeSRational"; break; } sb.Append(string.Format( "\tType:{0}\r\n"+ "\tLength:{1}\r\n"+ "\tValues:\r\n{2}\r\n", t,i.Len,DumpValues(i.Value) )); } this.textBox1.Text=sb.ToString(); } } } } Copyright 2003 Robert W. Powell. All Rights Reserved. |