[转]数码照片的JPG文件高级信息(用C#读取图片的EXIF信息)

      数码相机的照片很多,而且文件名也不直观,所以写了个程序批量改名,就是把文件名都改成相机的拍照日期,呵呵,谁知道拍照日期不是那么好取,在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 == nullcontinue;
379//
380data += name + "";
381//
382//1 = BYTE An 8-bit unsigned integer.,
383if (p.Type == 0x1)
384{
385= 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
391= 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
400= "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:
478= 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
486= 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
505= "F/" + Math.Round(Math.Pow(Math.Sqrt(2), r.ToDouble()), 2).ToString();
506break;
507case 0x920A:
508= r.ToDouble().ToString();
509break;
510case 0x829A:
511= r.ToDouble().ToString();
512break;
513case 0x829D// F-number
514= "F/" + r.ToDouble().ToString();
515break;
516default:
517= 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{
531= "DSC";
532}

533else
534{
535= "reserved";
536}

537break;
538}

539case 0xA301:
540if (p.Value[0== 1)
541= "A directly photographed image";
542else
543= "Not a directly photographed image";
544break;
545default:
546= "-";
547break;
548}

549}

550//9 = SLONG A 32-bit (4 -byte) signed integer (2's complement notation),
551else if (p.Type == 0x9)
552{
553= 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
574= "1/" + Math.Round(Math.Pow(2, r.ToDouble()), 2).ToString();
575break;
576case 0x9203:
577= Math.Round(r.ToDouble(), 4).ToString();
578break;
579default:
580= 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

你可能感兴趣的:([转]数码照片的JPG文件高级信息(用C#读取图片的EXIF信息))