数码相机的照片很多,而且文件名也不直观,所以写了个程序批量改名,就是把文件名都改成相机的拍照日期,呵呵,谁知道拍照日期不是那么好取,在csdn里开了一帖,谢谢网友帮忙,终于搞定!把代码放在下面了,说不定谁会用得着。
原帖地址:http://community.csdn.net/Expert/topic/4295/4295730.xml?temp=.662182
原文地址:http://www.codeproject.com/csharp/EXIFextractor.asp
////调用
string strFile="fffff.jpg";//文件名
System.Drawing.Bitmap bmp = new Bitmap(strFile);
EXIF.EXIFextractor er = new EXIF.EXIFextractor(ref bmp, "\n");
Console.Write(strFile + "\r\n");
Console.Write(er["DTDigitized"]);//拍照日期
foreach (EXIF.Pair pr in er)
{
Console.Write(pr.First + ":" + pr.Second + "\r\n");
}
//////////////////////////////////////////////////////////////////////////////////////
///下面的两个文件处理JPG的EXIF信息
Code
1/**////EXIFextractor.cs
2///
3using System;
4using System.Text;
5using System.Collections;
6using System.Drawing.Imaging;
7using System.Reflection;
8using System.IO;
9
10namespace EXIF
11{
12/**////
13/// EXIFextractor Class
14///
15///
16public class EXIFextractor : IEnumerable
17{
18/**////
19/// Get the individual property value by supplying property name
20/// These are the valid property names :
21///
22/// "Exif IFD"
23/// "Gps IFD"
24/// "New Subfile Type"
25/// "Subfile Type"
26/// "Image Width"
27/// "Image Height"
28/// "Bits Per Sample"
29/// "Compression"
30/// "Photometric Interp"
31/// "Thresh Holding"
32/// "Cell Width"
33/// "Cell Height"
34/// "Fill Order"
35/// "Document Name"
36/// "Image Description"
37/// "Equip Make"
38/// "Equip Model"
39/// "Strip Offsets"
40/// "Orientation"
41/// "Samples PerPixel"
42/// "Rows Per Strip"
43/// "Strip Bytes Count"
44/// "Min Sample Value"
45/// "Max Sample Value"
46/// "X Resolution"
47/// "Y Resolution"
48/// "Planar Config"
49/// "Page Name"
50/// "X Position"
51/// "Y Position"
52/// "Free Offset"
53/// "Free Byte Counts"
54/// "Gray Response Unit"
55/// "Gray Response Curve"
56/// "T4 Option"
57/// "T6 Option"
58/// "Resolution Unit"
59/// "Page Number"
60/// "Transfer Funcition"
61/// "Software Used"
62/// "Date Time"
63/// "Artist"
64/// "Host Computer"
65/// "Predictor"
66/// "White Point"
67/// "Primary Chromaticities"
68/// "ColorMap"
69/// "Halftone Hints"
70/// "Tile Width"
71/// "Tile Length"
72/// "Tile Offset"
73/// "Tile ByteCounts"
74/// "InkSet"
75/// "Ink Names"
76/// "Number Of Inks"
77/// "Dot Range"
78/// "Target Printer"
79/// "Extra Samples"
80/// "Sample Format"
81/// "S Min Sample Value"
82/// "S Max Sample Value"
83/// "Transfer Range"
84/// "JPEG Proc"
85/// "JPEG InterFormat"
86/// "JPEG InterLength"
87/// "JPEG RestartInterval"
88/// "JPEG LosslessPredictors"
89/// "JPEG PointTransforms"
90/// "JPEG QTables"
91/// "JPEG DCTables"
92/// "JPEG ACTables"
93/// "YCbCr Coefficients"
94/// "YCbCr Subsampling"
95/// "YCbCr Positioning"
96/// "REF Black White"
97/// "ICC Profile"
98/// "Gamma"
99/// "ICC Profile Descriptor"
100/// "SRGB RenderingIntent"
101/// "Image Title"
102/// "Copyright"
103/// "Resolution X Unit"
104/// "Resolution Y Unit"
105/// "Resolution X LengthUnit"
106/// "Resolution Y LengthUnit"
107/// "Print Flags"
108/// "Print Flags Version"
109/// "Print Flags Crop"
110/// "Print Flags Bleed Width"
111/// "Print Flags Bleed Width Scale"
112/// "Halftone LPI"
113/// "Halftone LPIUnit"
114/// "Halftone Degree"
115/// "Halftone Shape"
116/// "Halftone Misc"
117/// "Halftone Screen"
118/// "JPEG Quality"
119/// "Grid Size"
120/// "Thumbnail Format"
121/// "Thumbnail Width"
122/// "Thumbnail Height"
123/// "Thumbnail ColorDepth"
124/// "Thumbnail Planes"
125/// "Thumbnail RawBytes"
126/// "Thumbnail Size"
127/// "Thumbnail CompressedSize"
128/// "Color Transfer Function"
129/// "Thumbnail Data"
130/// "Thumbnail ImageWidth"
131/// "Thumbnail ImageHeight"
132/// "Thumbnail BitsPerSample"
133/// "Thumbnail Compression"
134/// "Thumbnail PhotometricInterp"
135/// "Thumbnail ImageDescription"
136/// "Thumbnail EquipMake"
137/// "Thumbnail EquipModel"
138/// "Thumbnail StripOffsets"
139/// "Thumbnail Orientation"
140/// "Thumbnail SamplesPerPixel"
141/// "Thumbnail RowsPerStrip"
142/// "Thumbnail StripBytesCount"
143/// "Thumbnail ResolutionX"
144/// "Thumbnail ResolutionY"
145/// "Thumbnail PlanarConfig"
146/// "Thumbnail ResolutionUnit"
147/// "Thumbnail TransferFunction"
148/// "Thumbnail SoftwareUsed"
149/// "Thumbnail DateTime"
150/// "Thumbnail Artist"
151/// "Thumbnail WhitePoint"
152/// "Thumbnail PrimaryChromaticities"
153/// "Thumbnail YCbCrCoefficients"
154/// "Thumbnail YCbCrSubsampling"
155/// "Thumbnail YCbCrPositioning"
156/// "Thumbnail RefBlackWhite"
157/// "Thumbnail CopyRight"
158/// "Luminance Table"
159/// "Chrominance Table"
160/// "Frame Delay"
161/// "Loop Count"
162/// "Pixel Unit"
163/// "Pixel PerUnit X"
164/// "Pixel PerUnit Y"
165/// "Palette Histogram"
166/// "Exposure Time"
167/// "F-Number"
168/// "Exposure Prog"
169/// "Spectral Sense"
170/// "ISO Speed"
171/// "OECF"
172/// "Ver"
173/// "DTOrig"
174/// "DTDigitized"
175/// "CompConfig"
176/// "CompBPP"
177/// "Shutter Speed"
178/// "Aperture"
179/// "Brightness"
180/// "Exposure Bias"
181/// "MaxAperture"
182/// "SubjectDist"
183/// "Metering Mode"
184/// "LightSource"
185/// "Flash"
186/// "FocalLength"
187/// "Maker Note"
188/// "User Comment"
189/// "DTSubsec"
190/// "DTOrigSS"
191/// "DTDigSS"
192/// "FPXVer"
193/// "ColorSpace"
194/// "PixXDim"
195/// "PixYDim"
196/// "RelatedWav"
197/// "Interop"
198/// "FlashEnergy"
199/// "SpatialFR"
200/// "FocalXRes"
201/// "FocalYRes"
202/// "FocalResUnit"
203/// "Subject Loc"
204/// "Exposure Index"
205/// "Sensing Method"
206/// "FileSource"
207/// "SceneType"
208/// "CfaPattern"
209/// "Gps Ver"
210/// "Gps LatitudeRef"
211/// "Gps Latitude"
212/// "Gps LongitudeRef"
213/// "Gps Longitude"
214/// "Gps AltitudeRef"
215/// "Gps Altitude"
216/// "Gps GpsTime"
217/// "Gps GpsSatellites"
218/// "Gps GpsStatus"
219/// "Gps GpsMeasureMode"
220/// "Gps GpsDop"
221/// "Gps SpeedRef"
222/// "Gps Speed"
223/// "Gps TrackRef"
224/// "Gps Track"
225/// "Gps ImgDirRef"
226/// "Gps ImgDir"
227/// "Gps MapDatum"
228/// "Gps DestLatRef"
229/// "Gps DestLat"
230/// "Gps DestLongRef"
231/// "Gps DestLong"
232/// "Gps DestBearRef"
233/// "Gps DestBear"
234/// "Gps DestDistRef"
235/// "Gps DestDist"
236///
237public object this[string index]
238{
239get
240{
241return properties[index];
242}
243}
244//
245private System.Drawing.Bitmap bmp;
246//
247private string data;
248//
249private translation myHash;
250//
251private Hashtable properties;
252//
253internal int Count
254{
255get
256{
257return this.properties.Count;
258}
259}
260//
261string sp;
262/**////
263///
264///
265///
266///
267///
268///
269public void setTag(int id, string data)
270{
271Encoding ascii = Encoding.ASCII;
272this.setTag(id, data.Length, 0x2, ascii.GetBytes(data));
273}
274/**////
275///
276///
277///
278///
279///
280///
281public void setTag(int id, int len, short type, byte[] data)
282{
283PropertyItem p = CreatePropertyItem(type, id, len, data);
284this.bmp.SetPropertyItem(p);
285buildDB(this.bmp.PropertyItems);
286}
287/**////
288///
289///
290///
291///
292///
293///
294///
295private static PropertyItem CreatePropertyItem(short type, int tag, int len, byte[] value)
296{
297PropertyItem item;
298
299// Loads a PropertyItem from a Jpeg image stored in the assembly as a resource.
300Assembly assembly = Assembly.GetExecutingAssembly();
301Stream emptyBitmapStream = assembly.GetManifestResourceStream("EXIFextractor.decoy.jpg");
302System.Drawing.Image empty = System.Drawing.Image.FromStream(emptyBitmapStream);
303
304item = empty.PropertyItems[0];
305
306// Copies the data to the property item.
307item.Type = type;
308item.Len = len;
309item.Id = tag;
310item.Value = new byte[value.Length];
311value.CopyTo(item.Value, 0);
312
313return item;
314}
315/**////
316///
317///
318///
319///
320public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp)
321{
322properties = new Hashtable();
323//
324this.bmp = bmp;
325this.sp = sp;
326//
327myHash = new translation();
328buildDB(this.bmp.PropertyItems);
329}
330string msp = "";
331public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp, string msp)
332{
333properties = new Hashtable();
334this.sp = sp;
335this.msp = msp;
336this.bmp = bmp;
337//
338myHash = new translation();
339this.buildDB(bmp.PropertyItems);
340
341}
342public static PropertyItem[] GetExifProperties(string fileName)
343{
344FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
345System.Drawing.Image image = System.Drawing.Image.FromStream(stream,
346/**//* useEmbeddedColorManagement = */ true,
347/**//* validateImageData = */ false);
348return image.PropertyItems;
349}
350public EXIFextractor(string file, string sp, string msp)
351{
352properties = new Hashtable();
353this.sp = sp;
354this.msp = msp;
355
356myHash = new translation();
357//
358this.buildDB(GetExifProperties(file));
359
360}
361
362/**////
363///
364///
365private void buildDB(System.Drawing.Imaging.PropertyItem[] parr)
366{
367properties.Clear();
368//
369data = "";
370//
371Encoding ascii = Encoding.ASCII;
372//
373foreach (System.Drawing.Imaging.PropertyItem p in parr)
374{
375string v = "";
376string name = (string)myHash[p.Id];
377// tag not found. skip it
378if (name == null) continue;
379//
380data += name + ": ";
381//
382//1 = BYTE An 8-bit unsigned integer.,
383if (p.Type == 0x1)
384{
385v = p.Value[0].ToString();
386}
387//2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL.,
388else if (p.Type == 0x2)
389{
390// string
391v = ascii.GetString(p.Value);
392}
393//3 = SHORT A 16-bit (2 -byte) unsigned integer,
394else if (p.Type == 0x3)
395{
396// orientation // lookup table
397switch (p.Id)
398{
399case 0x8827: // ISO
400v = "ISO-" + convertToInt16U(p.Value).ToString();
401break;
402case 0xA217: // sensing method
403{
404switch (convertToInt16U(p.Value))
405{
406case 1: v = "Not defined"; break;
407case 2: v = "One-chip color area sensor"; break;
408case 3: v = "Two-chip color area sensor"; break;
409case 4: v = "Three-chip color area sensor"; break;
410case 5: v = "Color sequential area sensor"; break;
411case 7: v = "Trilinear sensor"; break;
412case 8: v = "Color sequential linear sensor"; break;
413default: v = " reserved"; break;
414}
415}
416break;
417case 0x8822: // aperture
418switch (convertToInt16U(p.Value))
419{
420case 0: v = "Not defined"; break;
421case 1: v = "Manual"; break;
422case 2: v = "Normal program"; break;
423case 3: v = "Aperture priority"; break;
424case 4: v = "Shutter priority"; break;
425case 5: v = "Creative program (biased toward depth of field)"; break;
426case 6: v = "Action program (biased toward fast shutter speed)"; break;
427case 7: v = "Portrait mode (for closeup photos with the background out of focus)"; break;
428case 8: v = "Landscape mode (for landscape photos with the background in focus)"; break;
429default: v = "reserved"; break;
430}
431break;
432case 0x9207: // metering mode
433switch (convertToInt16U(p.Value))
434{
435case 0: v = "unknown"; break;
436case 1: v = "Average"; break;
437case 2: v = "CenterWeightedAverage"; break;
438case 3: v = "Spot"; break;
439case 4: v = "MultiSpot"; break;
440case 5: v = "Pattern"; break;
441case 6: v = "Partial"; break;
442case 255: v = "Other"; break;
443default: v = "reserved"; break;
444}
445break;
446case 0x9208: // light source
447{
448switch (convertToInt16U(p.Value))
449{
450case 0: v = "unknown"; break;
451case 1: v = "Daylight"; break;
452case 2: v = "Fluorescent"; break;
453case 3: v = "Tungsten"; break;
454case 17: v = "Standard light A"; break;
455case 18: v = "Standard light B"; break;
456case 19: v = "Standard light C"; break;
457case 20: v = "D55"; break;
458case 21: v = "D65"; break;
459case 22: v = "D75"; break;
460case 255: v = "other"; break;
461default: v = "reserved"; break;
462}
463}
464break;
465case 0x9209:
466{
467switch (convertToInt16U(p.Value))
468{
469case 0: v = "Flash did not fire"; break;
470case 1: v = "Flash fired"; break;
471case 5: v = "Strobe return light not detected"; break;
472case 7: v = "Strobe return light detected"; break;
473default: v = "reserved"; break;
474}
475}
476break;
477default:
478v = convertToInt16U(p.Value).ToString();
479break;
480}
481}
482//4 = LONG A 32-bit (4 -byte) unsigned integer,
483else if (p.Type == 0x4)
484{
485// orientation // lookup table
486v = convertToInt32U(p.Value).ToString();
487}
488//5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the//denominator.,
489else if (p.Type == 0x5)
490{
491// rational
492byte[] n = new byte[p.Len / 2];
493byte[] d = new byte[p.Len / 2];
494Array.Copy(p.Value, 0, n, 0, p.Len / 2);
495Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
496uint a = convertToInt32U(n);
497uint b = convertToInt32U(d);
498Rational r = new Rational(a, b);
499//
500//convert here
501//
502switch (p.Id)
503{
504case 0x9202: // aperture
505v = "F/" + Math.Round(Math.Pow(Math.Sqrt(2), r.ToDouble()), 2).ToString();
506break;
507case 0x920A:
508v = r.ToDouble().ToString();
509break;
510case 0x829A:
511v = r.ToDouble().ToString();
512break;
513case 0x829D: // F-number
514v = "F/" + r.ToDouble().ToString();
515break;
516default:
517v = r.ToString("/");
518break;
519}
520
521}
522//7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
523else if (p.Type == 0x7)
524{
525switch (p.Id)
526{
527case 0xA300:
528{
529if (p.Value[0] == 3)
530{
531v = "DSC";
532}
533else
534{
535v = "reserved";
536}
537break;
538}
539case 0xA301:
540if (p.Value[0] == 1)
541v = "A directly photographed image";
542else
543v = "Not a directly photographed image";
544break;
545default:
546v = "-";
547break;
548}
549}
550//9 = SLONG A 32-bit (4 -byte) signed integer (2's complement notation),
551else if (p.Type == 0x9)
552{
553v = convertToInt32(p.Value).ToString();
554}
555//10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
556//denominator.
557else if (p.Type == 0xA)
558{
559
560// rational
561byte[] n = new byte[p.Len / 2];
562byte[] d = new byte[p.Len / 2];
563Array.Copy(p.Value, 0, n, 0, p.Len / 2);
564Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
565int a = convertToInt32(n);
566int b = convertToInt32(d);
567Rational r = new Rational(a, b);
568//
569// convert here
570//
571switch (p.Id)
572{
573case 0x9201: // shutter speed
574v = "1/" + Math.Round(Math.Pow(2, r.ToDouble()), 2).ToString();
575break;
576case 0x9203:
577v = Math.Round(r.ToDouble(), 4).ToString();
578break;
579default:
580v = r.ToString("/");
581break;
582}
583}
584// add it to the list
585if (properties[name] == null)
586properties.Add(name, v);
587// cat it too
588data += v;
589data += this.sp;
590}
591
592}
593
594/**////
595///
596///
597///
598public override string ToString()
599{
600return data;
601}
602/**////
603///
604///
605///
606///
607int convertToInt32(byte[] arr)
608{
609if (arr.Length != 4)
610return 0;
611else
612return arr[3];
613
614}
615
1/**////EXIFextractor.cs
2///
3using System;
4using System.Text;
5using System.Collections;
6using System.Drawing.Imaging;
7using System.Reflection;
8using System.IO;
9
10namespace EXIF
11{
12/**////
13/// EXIFextractor Class
14///
15///
16public class EXIFextractor : IEnumerable
17{
18/**////
19/// Get the individual property value by supplying property name
20/// These are the valid property names :
21///
22/// "Exif IFD"
23/// "Gps IFD"
24/// "New Subfile Type"
25/// "Subfile Type"
26/// "Image Width"
27/// "Image Height"
28/// "Bits Per Sample"
29/// "Compression"
30/// "Photometric Interp"
31/// "Thresh Holding"
32/// "Cell Width"
33/// "Cell Height"
34/// "Fill Order"
35/// "Document Name"
36/// "Image Description"
37/// "Equip Make"
38/// "Equip Model"
39/// "Strip Offsets"
40/// "Orientation"
41/// "Samples PerPixel"
42/// "Rows Per Strip"
43/// "Strip Bytes Count"
44/// "Min Sample Value"
45/// "Max Sample Value"
46/// "X Resolution"
47/// "Y Resolution"
48/// "Planar Config"
49/// "Page Name"
50/// "X Position"
51/// "Y Position"
52/// "Free Offset"
53/// "Free Byte Counts"
54/// "Gray Response Unit"
55/// "Gray Response Curve"
56/// "T4 Option"
57/// "T6 Option"
58/// "Resolution Unit"
59/// "Page Number"
60/// "Transfer Funcition"
61/// "Software Used"
62/// "Date Time"
63/// "Artist"
64/// "Host Computer"
65/// "Predictor"
66/// "White Point"
67/// "Primary Chromaticities"
68/// "ColorMap"
69/// "Halftone Hints"
70/// "Tile Width"
71/// "Tile Length"
72/// "Tile Offset"
73/// "Tile ByteCounts"
74/// "InkSet"
75/// "Ink Names"
76/// "Number Of Inks"
77/// "Dot Range"
78/// "Target Printer"
79/// "Extra Samples"
80/// "Sample Format"
81/// "S Min Sample Value"
82/// "S Max Sample Value"
83/// "Transfer Range"
84/// "JPEG Proc"
85/// "JPEG InterFormat"
86/// "JPEG InterLength"
87/// "JPEG RestartInterval"
88/// "JPEG LosslessPredictors"
89/// "JPEG PointTransforms"
90/// "JPEG QTables"
91/// "JPEG DCTables"
92/// "JPEG ACTables"
93/// "YCbCr Coefficients"
94/// "YCbCr Subsampling"
95/// "YCbCr Positioning"
96/// "REF Black White"
97/// "ICC Profile"
98/// "Gamma"
99/// "ICC Profile Descriptor"
100/// "SRGB RenderingIntent"
101/// "Image Title"
102/// "Copyright"
103/// "Resolution X Unit"
104/// "Resolution Y Unit"
105/// "Resolution X LengthUnit"
106/// "Resolution Y LengthUnit"
107/// "Print Flags"
108/// "Print Flags Version"
109/// "Print Flags Crop"
110/// "Print Flags Bleed Width"
111/// "Print Flags Bleed Width Scale"
112/// "Halftone LPI"
113/// "Halftone LPIUnit"
114/// "Halftone Degree"
115/// "Halftone Shape"
116/// "Halftone Misc"
117/// "Halftone Screen"
118/// "JPEG Quality"
119/// "Grid Size"
120/// "Thumbnail Format"
121/// "Thumbnail Width"
122/// "Thumbnail Height"
123/// "Thumbnail ColorDepth"
124/// "Thumbnail Planes"
125/// "Thumbnail RawBytes"
126/// "Thumbnail Size"
127/// "Thumbnail CompressedSize"
128/// "Color Transfer Function"
129/// "Thumbnail Data"
130/// "Thumbnail ImageWidth"
131/// "Thumbnail ImageHeight"
132/// "Thumbnail BitsPerSample"
133/// "Thumbnail Compression"
134/// "Thumbnail PhotometricInterp"
135/// "Thumbnail ImageDescription"
136/// "Thumbnail EquipMake"
137/// "Thumbnail EquipModel"
138/// "Thumbnail StripOffsets"
139/// "Thumbnail Orientation"
140/// "Thumbnail SamplesPerPixel"
141/// "Thumbnail RowsPerStrip"
142/// "Thumbnail StripBytesCount"
143/// "Thumbnail ResolutionX"
144/// "Thumbnail ResolutionY"
145/// "Thumbnail PlanarConfig"
146/// "Thumbnail ResolutionUnit"
147/// "Thumbnail TransferFunction"
148/// "Thumbnail SoftwareUsed"
149/// "Thumbnail DateTime"
150/// "Thumbnail Artist"
151/// "Thumbnail WhitePoint"
152/// "Thumbnail PrimaryChromaticities"
153/// "Thumbnail YCbCrCoefficients"
154/// "Thumbnail YCbCrSubsampling"
155/// "Thumbnail YCbCrPositioning"
156/// "Thumbnail RefBlackWhite"
157/// "Thumbnail CopyRight"
158/// "Luminance Table"
159/// "Chrominance Table"
160/// "Frame Delay"
161/// "Loop Count"
162/// "Pixel Unit"
163/// "Pixel PerUnit X"
164/// "Pixel PerUnit Y"
165/// "Palette Histogram"
166/// "Exposure Time"
167/// "F-Number"
168/// "Exposure Prog"
169/// "Spectral Sense"
170/// "ISO Speed"
171/// "OECF"
172/// "Ver"
173/// "DTOrig"
174/// "DTDigitized"
175/// "CompConfig"
176/// "CompBPP"
177/// "Shutter Speed"
178/// "Aperture"
179/// "Brightness"
180/// "Exposure Bias"
181/// "MaxAperture"
182/// "SubjectDist"
183/// "Metering Mode"
184/// "LightSource"
185/// "Flash"
186/// "FocalLength"
187/// "Maker Note"
188/// "User Comment"
189/// "DTSubsec"
190/// "DTOrigSS"
191/// "DTDigSS"
192/// "FPXVer"
193/// "ColorSpace"
194/// "PixXDim"
195/// "PixYDim"
196/// "RelatedWav"
197/// "Interop"
198/// "FlashEnergy"
199/// "SpatialFR"
200/// "FocalXRes"
201/// "FocalYRes"
202/// "FocalResUnit"
203/// "Subject Loc"
204/// "Exposure Index"
205/// "Sensing Method"
206/// "FileSource"
207/// "SceneType"
208/// "CfaPattern"
209/// "Gps Ver"
210/// "Gps LatitudeRef"
211/// "Gps Latitude"
212/// "Gps LongitudeRef"
213/// "Gps Longitude"
214/// "Gps AltitudeRef"
215/// "Gps Altitude"
216/// "Gps GpsTime"
217/// "Gps GpsSatellites"
218/// "Gps GpsStatus"
219/// "Gps GpsMeasureMode"
220/// "Gps GpsDop"
221/// "Gps SpeedRef"
222/// "Gps Speed"
223/// "Gps TrackRef"
224/// "Gps Track"
225/// "Gps ImgDirRef"
226/// "Gps ImgDir"
227/// "Gps MapDatum"
228/// "Gps DestLatRef"
229/// "Gps DestLat"
230/// "Gps DestLongRef"
231/// "Gps DestLong"
232/// "Gps DestBearRef"
233/// "Gps DestBear"
234/// "Gps DestDistRef"
235/// "Gps DestDist"
236///
237public object this[string index]
238{
239get
240{
241return properties[index];
242}
243}
244//
245private System.Drawing.Bitmap bmp;
246//
247private string data;
248//
249private translation myHash;
250//
251private Hashtable properties;
252//
253internal int Count
254{
255get
256{
257return this.properties.Count;
258}
259}
260//
261string sp;
262/**////
263///
264///
265///
266///
267///
268///
269public void setTag(int id, string data)
270{
271Encoding ascii = Encoding.ASCII;
272this.setTag(id, data.Length, 0x2, ascii.GetBytes(data));
273}
274/**////
275///
276///
277///
278///
279///
280///
281public void setTag(int id, int len, short type, byte[] data)
282{
283PropertyItem p = CreatePropertyItem(type, id, len, data);
284this.bmp.SetPropertyItem(p);
285buildDB(this.bmp.PropertyItems);
286}
287/**////
288///
289///
290///
291///
292///
293///
294///
295private static PropertyItem CreatePropertyItem(short type, int tag, int len, byte[] value)
296{
297PropertyItem item;
298
299// Loads a PropertyItem from a Jpeg image stored in the assembly as a resource.
300Assembly assembly = Assembly.GetExecutingAssembly();
301Stream emptyBitmapStream = assembly.GetManifestResourceStream("EXIFextractor.decoy.jpg");
302System.Drawing.Image empty = System.Drawing.Image.FromStream(emptyBitmapStream);
303
304item = empty.PropertyItems[0];
305
306// Copies the data to the property item.
307item.Type = type;
308item.Len = len;
309item.Id = tag;
310item.Value = new byte[value.Length];
311value.CopyTo(item.Value, 0);
312
313return item;
314}
315/**////
316///
317///
318///
319///
320public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp)
321{
322properties = new Hashtable();
323//
324this.bmp = bmp;
325this.sp = sp;
326//
327myHash = new translation();
328buildDB(this.bmp.PropertyItems);
329}
330string msp = "";
331public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp, string msp)
332{
333properties = new Hashtable();
334this.sp = sp;
335this.msp = msp;
336this.bmp = bmp;
337//
338myHash = new translation();
339this.buildDB(bmp.PropertyItems);
340
341}
342public static PropertyItem[] GetExifProperties(string fileName)
343{
344FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
345System.Drawing.Image image = System.Drawing.Image.FromStream(stream,
346/**//* useEmbeddedColorManagement = */ true,
347/**//* validateImageData = */ false);
348return image.PropertyItems;
349}
350public EXIFextractor(string file, string sp, string msp)
351{
352properties = new Hashtable();
353this.sp = sp;
354this.msp = msp;
355
356myHash = new translation();
357//
358this.buildDB(GetExifProperties(file));
359
360}
361
362/**////
363///
364///
365private void buildDB(System.Drawing.Imaging.PropertyItem[] parr)
366{
367properties.Clear();
368//
369data = "";
370//
371Encoding ascii = Encoding.ASCII;
372//
373foreach (System.Drawing.Imaging.PropertyItem p in parr)
374{
375string v = "";
376string name = (string)myHash[p.Id];
377// tag not found. skip it
378if (name == null) continue;
379//
380data += name + ": ";
381//
382//1 = BYTE An 8-bit unsigned integer.,
383if (p.Type == 0x1)
384{
385v = p.Value[0].ToString();
386}
387//2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL.,
388else if (p.Type == 0x2)
389{
390// string
391v = ascii.GetString(p.Value);
392}
393//3 = SHORT A 16-bit (2 -byte) unsigned integer,
394else if (p.Type == 0x3)
395{
396// orientation // lookup table
397switch (p.Id)
398{
399case 0x8827: // ISO
400v = "ISO-" + convertToInt16U(p.Value).ToString();
401break;
402case 0xA217: // sensing method
403{
404switch (convertToInt16U(p.Value))
405{
406case 1: v = "Not defined"; break;
407case 2: v = "One-chip color area sensor"; break;
408case 3: v = "Two-chip color area sensor"; break;
409case 4: v = "Three-chip color area sensor"; break;
410case 5: v = "Color sequential area sensor"; break;
411case 7: v = "Trilinear sensor"; break;
412case 8: v = "Color sequential linear sensor"; break;
413default: v = " reserved"; break;
414}
415}
416break;
417case 0x8822: // aperture
418switch (convertToInt16U(p.Value))
419{
420case 0: v = "Not defined"; break;
421case 1: v = "Manual"; break;
422case 2: v = "Normal program"; break;
423case 3: v = "Aperture priority"; break;
424case 4: v = "Shutter priority"; break;
425case 5: v = "Creative program (biased toward depth of field)"; break;
426case 6: v = "Action program (biased toward fast shutter speed)"; break;
427case 7: v = "Portrait mode (for closeup photos with the background out of focus)"; break;
428case 8: v = "Landscape mode (for landscape photos with the background in focus)"; break;
429default: v = "reserved"; break;
430}
431break;
432case 0x9207: // metering mode
433switch (convertToInt16U(p.Value))
434{
435case 0: v = "unknown"; break;
436case 1: v = "Average"; break;
437case 2: v = "CenterWeightedAverage"; break;
438case 3: v = "Spot"; break;
439case 4: v = "MultiSpot"; break;
440case 5: v = "Pattern"; break;
441case 6: v = "Partial"; break;
442case 255: v = "Other"; break;
443default: v = "reserved"; break;
444}
445break;
446case 0x9208: // light source
447{
448switch (convertToInt16U(p.Value))
449{
450case 0: v = "unknown"; break;
451case 1: v = "Daylight"; break;
452case 2: v = "Fluorescent"; break;
453case 3: v = "Tungsten"; break;
454case 17: v = "Standard light A"; break;
455case 18: v = "Standard light B"; break;
456case 19: v = "Standard light C"; break;
457case 20: v = "D55"; break;
458case 21: v = "D65"; break;
459case 22: v = "D75"; break;
460case 255: v = "other"; break;
461default: v = "reserved"; break;
462}
463}
464break;
465case 0x9209:
466{
467switch (convertToInt16U(p.Value))
468{
469case 0: v = "Flash did not fire"; break;
470case 1: v = "Flash fired"; break;
471case 5: v = "Strobe return light not detected"; break;
472case 7: v = "Strobe return light detected"; break;
473default: v = "reserved"; break;
474}
475}
476break;
477default:
478v = convertToInt16U(p.Value).ToString();
479break;
480}
481}
482//4 = LONG A 32-bit (4 -byte) unsigned integer,
483else if (p.Type == 0x4)
484{
485// orientation // lookup table
486v = convertToInt32U(p.Value).ToString();
487}
488//5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the//denominator.,
489else if (p.Type == 0x5)
490{
491// rational
492byte[] n = new byte[p.Len / 2];
493byte[] d = new byte[p.Len / 2];
494Array.Copy(p.Value, 0, n, 0, p.Len / 2);
495Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
496uint a = convertToInt32U(n);
497uint b = convertToInt32U(d);
498Rational r = new Rational(a, b);
499//
500//convert here
501//
502switch (p.Id)
503{
504case 0x9202: // aperture
505v = "F/" + Math.Round(Math.Pow(Math.Sqrt(2), r.ToDouble()), 2).ToString();
506break;
507case 0x920A:
508v = r.ToDouble().ToString();
509break;
510case 0x829A:
511v = r.ToDouble().ToString();
512break;
513case 0x829D: // F-number
514v = "F/" + r.ToDouble().ToString();
515break;
516default:
517v = r.ToString("/");
518break;
519}
520
521}
522//7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
523else if (p.Type == 0x7)
524{
525switch (p.Id)
526{
527case 0xA300:
528{
529if (p.Value[0] == 3)
530{
531v = "DSC";
532}
533else
534{
535v = "reserved";
536}
537break;
538}
539case 0xA301:
540if (p.Value[0] == 1)
541v = "A directly photographed image";
542else
543v = "Not a directly photographed image";
544break;
545default:
546v = "-";
547break;
548}
549}
550//9 = SLONG A 32-bit (4 -byte) signed integer (2's complement notation),
551else if (p.Type == 0x9)
552{
553v = convertToInt32(p.Value).ToString();
554}
555//10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
556//denominator.
557else if (p.Type == 0xA)
558{
559
560// rational
561byte[] n = new byte[p.Len / 2];
562byte[] d = new byte[p.Len / 2];
563Array.Copy(p.Value, 0, n, 0, p.Len / 2);
564Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
565int a = convertToInt32(n);
566int b = convertToInt32(d);
567Rational r = new Rational(a, b);
568//
569// convert here
570//
571switch (p.Id)
572{
573case 0x9201: // shutter speed
574v = "1/" + Math.Round(Math.Pow(2, r.ToDouble()), 2).ToString();
575break;
576case 0x9203:
577v = Math.Round(r.ToDouble(), 4).ToString();
578break;
579default:
580v = r.ToString("/");
581break;
582}
583}
584// add it to the list
585if (properties[name] == null)
586properties.Add(name, v);
587// cat it too
588data += v;
589data += this.sp;
590}
591
592}
593
594/**////
595///
596///
597///
598public override string ToString()
599{
600return data;
601}
602/**////
603///
604///
605///
606///
607int convertToInt32(byte[] arr)
608{
609if (arr.Length != 4)
610return 0;
611else
612return arr[3];
613
614}
615