数码相机的照片很多,而且文件名也不直观,所以写了个程序批量改名,就是把文件名都改成相机的拍照日期,呵呵,谁知道拍照日期不是那么好取,在csdn里开了一帖,谢谢网友帮忙,终于搞定!把代码放在下面了,说不定谁会用得着。
原帖地址:http://community.youkuaiyun.com/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
///
3
using System;
4
using System.Text;
5
using System.Collections;
6
using System.Drawing.Imaging;
7
using System.Reflection;
8
using System.IO;
9
10
namespace EXIF
11

{
12
/**////
13
/// EXIFextractor Class
14
///
15
///
16
public 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
///
237
public object this[string index]
238

{
239
get
240

{
241
return properties[index];
242
}
243
}
244
//
245
private System.Drawing.Bitmap bmp;
246
//
247
private string data;
248
//
249
private translation myHash;
250
//
251
private Hashtable properties;
252
//
253
internal int Count
254

{
255
get
256

{
257
return this.properties.Count;
258
}
259
}
260
//
261
string sp;
262
/**////
263
///
264
///
265
///
266
///
267
///
268
///
269
public void setTag(int id, string data)
270

{
271
Encoding ascii = Encoding.ASCII;
272
this.setTag(id, data.Length, 0x2, ascii.GetBytes(data));
273
}
274
/**////
275
///
276
///
277
///
278
///
279
///
280
///
281
public void setTag(int id, int len, short type, byte[] data)
282

{
283
PropertyItem p = CreatePropertyItem(type, id, len, data);
284
this.bmp.SetPropertyItem(p);
285
buildDB(this.bmp.PropertyItems);
286
}
287
/**////
288
///
289
///
290
///
291
///
292
///
293
///
294
///
295
private static PropertyItem CreatePropertyItem(short type, int tag, int len, byte[] value)
296

{
297
PropertyItem item;
298
299
// Loads a PropertyItem from a Jpeg image stored in the assembly as a resource.
300
Assembly assembly = Assembly.GetExecutingAssembly();
301
Stream emptyBitmapStream = assembly.GetManifestResourceStream("EXIFextractor.decoy.jpg");
302
System.Drawing.Image empty = System.Drawing.Image.FromStream(emptyBitmapStream);
303
304
item = empty.PropertyItems[0];
305
306
// Copies the data to the property item.
307
item.Type = type;
308
item.Len = len;
309
item.Id = tag;
310
item.Value = new byte[value.Length];
311
value.CopyTo(item.Value, 0);
312
313
return item;
314
}
315
/**////
316
///
317
///
318
///
319
///
320
public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp)
321

{
322
properties = new Hashtable();
323
//
324
this.bmp = bmp;
325
this.sp = sp;
326
//
327
myHash = new translation();
328
buildDB(this.bmp.PropertyItems);
329
}
330
string msp = "";
331
public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp, string msp)
332

{
333
properties = new Hashtable();
334
this.sp = sp;
335
this.msp = msp;
336
this.bmp = bmp;
337
//
338
myHash = new translation();
339
this.buildDB(bmp.PropertyItems);
340
341
}
342
public static PropertyItem[] GetExifProperties(string fileName)
343

{
344
FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
345
System.Drawing.Image image = System.Drawing.Image.FromStream(stream,
346
/**//* useEmbeddedColorManagement = */ true,
347
/**//* validateImageData = */ false);
348
return image.PropertyItems;
349
}
350
public EXIFextractor(string file, string sp, string msp)
351

{
352
properties = new Hashtable();
353
this.sp = sp;
354
this.msp = msp;
355
356
myHash = new translation();
357
//
358
this.buildDB(GetExifProperties(file));
359
360
}
361
362
/**////
363
///
364
///
365
private void buildDB(System.Drawing.Imaging.PropertyItem[] parr)
366

{
367
properties.Clear();
368
//
369
data = "";
370
//
371
Encoding ascii = Encoding.ASCII;
372
//
373
foreach (System.Drawing.Imaging.PropertyItem p in parr)
374

{
375
string v = "";
376
string name = (string)myHash[p.Id];
377
// tag not found. skip it
378
if (name == null) continue;
379
//
380
data += name + ": ";
381
//
382
//1 = BYTE An 8-bit unsigned integer.,
383
if (p.Type == 0x1)
384

{
385
v = 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.,
388
else if (p.Type == 0x2)
389

{
390
// string
391
v = ascii.GetString(p.Value);
392
}
393
//3 = SHORT A 16-bit (2 -byte) unsigned integer,
394
else if (p.Type == 0x3)
395

{
396
// orientation // lookup table
397
switch (p.Id)
398

{
399
case 0x8827: // ISO
400
v = "ISO-" + convertToInt16U(p.Value).ToString();
401
break;
402
case 0xA217: // sensing method
403

{
404
switch (convertToInt16U(p.Value))
405

{
406
case 1: v = "Not defined"; break;
407
case 2: v = "One-chip color area sensor"; break;
408
case 3: v = "Two-chip color area sensor"; break;
409
case 4: v = "Three-chip color area sensor"; break;
410
case 5: v = "Color sequential area sensor"; break;
411
case 7: v = "Trilinear sensor"; break;
412
case 8: v = "Color sequential linear sensor"; break;
413
default: v = " reserved"; break;
414
}
415
}
416
break;
417
case 0x8822: // aperture
418
switch (convertToInt16U(p.Value))
419

{
420
case 0: v = "Not defined"; break;
421
case 1: v = "Manual"; break;
422
case 2: v = "Normal program"; break;
423
case 3: v = "Aperture priority"; break;
424
case 4: v = "Shutter priority"; break;
425
case 5: v = "Creative program (biased toward depth of field)"; break;
426
case 6: v = "Action program (biased toward fast shutter speed)"; break;
427
case 7: v = "Portrait mode (for closeup photos with the background out of focus)"; break;
428
case 8: v = "Landscape mode (for landscape photos with the background in focus)"; break;
429
default: v = "reserved"; break;
430
}
431
break;
432
case 0x9207: // metering mode
433
switch (convertToInt16U(p.Value))
434

{
435
case 0: v = "unknown"; break;
436
case 1: v = "Average"; break;
437
case 2: v = "CenterWeightedAverage"; break;
438
case 3: v = "Spot"; break;
439
case 4: v = "MultiSpot"; break;
440
case 5: v = "Pattern"; break;
441
case 6: v = "Partial"; break;
442
case 255: v = "Other"; break;
443
default: v = "reserved"; break;
444
}
445
break;
446
case 0x9208: // light source
447

{
448
switch (convertToInt16U(p.Value))
449

{
450
case 0: v = "unknown"; break;
451
case 1: v = "Daylight"; break;
452
case 2: v = "Fluorescent"; break;
453
case 3: v = "Tungsten"; break;
454
case 17: v = "Standard light A"; break;
455
case 18: v = "Standard light B"; break;
456
case 19: v = "Standard light C"; break;
457
case 20: v = "D55"; break;
458
case 21: v = "D65"; break;
459
case 22: v = "D75"; break;
460
case 255: v = "other"; break;
461
default: v = "reserved"; break;
462
}
463
}
464
break;
465
case 0x9209:
466

{
467
switch (convertToInt16U(p.Value))
468

{
469
case 0: v = "Flash did not fire"; break;
470
case 1: v = "Flash fired"; break;
471
case 5: v = "Strobe return light not detected"; break;
472
case 7: v = "Strobe return light detected"; break;
473
default: v = "reserved"; break;
474
}
475
}
476
break;
477
default:
478
v = convertToInt16U(p.Value).ToString();
479
break;
480
}
481
}
482
//4 = LONG A 32-bit (4 -byte) unsigned integer,
483
else if (p.Type == 0x4)
484

{
485
// orientation // lookup table
486
v = convertToInt32U(p.Value).ToString();
487
}
488
//5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the//denominator.,
489
else if (p.Type == 0x5)
490

{
491
// rational
492
byte[] n = new byte[p.Len / 2];
493
byte[] d = new byte[p.Len / 2];
494
Array.Copy(p.Value, 0, n, 0, p.Len / 2);
495
Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
496
uint a = convertToInt32U(n);
497
uint b = convertToInt32U(d);
498
Rational r = new Rational(a, b);
499
//
500
//convert here
501
//
502
switch (p.Id)
503

{
504
case 0x9202: // aperture
505
v = "F/" + Math.Round(Math.Pow(Math.Sqrt(2), r.ToDouble()), 2).ToString();
506
break;
507
case 0x920A:
508
v = r.ToDouble().ToString();
509
break;
510
case 0x829A:
511
v = r.ToDouble().ToString();
512
break;
513
case 0x829D: // F-number
514
v = "F/" + r.ToDouble().ToString();
515
break;
516
default:
517
v = r.ToString("/");
518
break;
519
}
520
521
}
522
//7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
523
else if (p.Type == 0x7)
524

{
525
switch (p.Id)
526

{
527
case 0xA300:
528

{
529
if (p.Value[0] == 3)
530

{
531
v = "DSC";
532
}
533
else
534

{
535
v = "reserved";
536
}
537
break;
538
}
539
case 0xA301:
540
if (p.Value[0] == 1)
541
v = "A directly photographed image";
542
else
543
v = "Not a directly photographed image";
544
break;
545
default:
546
v = "-";
547
break;
548
}
549
}
550
//9 = SLONG A 32-bit (4 -byte) signed integer (2's complement notation),
551
else if (p.Type == 0x9)
552

{
553
v = convertToInt32(p.Value).ToString();
554
}
555
//10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
556
//denominator.
557
else if (p.Type == 0xA)
558

{
559
560
// rational
561
byte[] n = new byte[p.Len / 2];
562
byte[] d = new byte[p.Len / 2];
563
Array.Copy(p.Value, 0, n, 0, p.Len / 2);
564
Array.Copy(p.Value, p.Len / 2, d, 0, p.Len / 2);
565
int a = convertToInt32(n);
566
int b = convertToInt32(d);
567
Rational r = new Rational(a, b);
568
//
569
// convert here
570
//
571
switch (p.Id)
572

{
573
case 0x9201: // shutter speed
574
v = "1/" + Math.Round(Math.Pow(2, r.ToDouble()), 2).ToString();
575
break;
576
case 0x9203:
577
v = Math.Round(r.ToDouble(), 4).ToString();
578
break;
579
default:
580
v = r.ToString("/");
581
break;
582
}
583
}
584
// add it to the list
585
if (properties[name] == null)
586
properties.Add(name, v);
587
// cat it too
588
data += v;
589
data += this.sp;
590
}
591
592
}
593
594
/**////
595
///
596
///
597
///
598
public override string ToString()
599

{
600
return data;
601
}
602
/**////
603
///
604
///
605
///
606
///
607
int convertToInt32(byte[] arr)
608

{
609
if (arr.Length != 4)
610
return 0;
611
else
612
return arr[3];
613
614
}
615