C# Exif code,metadata extraction in java读取照片文件的属性

FROM: http://sourceforge.net/projects/metadataspr/

http://www.drewnoakes.com/code/exif/

http://www.holmessoft.co.uk/homepage/Software/ExifUsage.htm

http://www.exif.org/samples.html

Write EXIF metadata to a jpeg file http://www.dreamincode.net/code/snippet3144.htm

代码
  1    
  2       public ModifyJpgMetadata()   
  3    
  4       {   
  5    
  6           //   
  7    
  8           // get the path to some jpg file   
  9    
 10           //   
 11    
 12           string jpegPath = "C:\\users\\scott\\Pictures\\sample\\xxxjpg";   
 13    
 14           string jpegDirectory = PathGetDirectoryName(jpegPath);   
 15    
 16           string jpegFileName = PathGetFileNameWithoutExtension(jpegPath);   
 17    
 18           string jpegExtension = "jpg";   
 19   
 20        
 21   
 22           BitmapDecoder decoder = null;   
 23   
 24           BitmapFrame bitmapFrame = null;   
 25   
 26           BitmapMetadata metadata = null;   
 27   
 28           if (FileExists(jpegPath))   
 29   
 30           {   
 31   
 32               //   
 33   
 34               // load the jpg file with a JpegBitmapDecoder   
 35   
 36               //   
 37   
 38               using (Stream jpegStreamIn = FileOpen(jpegPath, FileModeOpen, FileAccessReadWrite, FileShareNone))   
 39   
 40               {   
 41   
 42                   decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptionsPreservePixelFormat, BitmapCacheOptionOnLoad);   
 43   
 44               }   
 45   
 46        
 47   
 48               bitmapFrame = decoderFrames[];   
 49   
 50               metadata = (BitmapMetadata)bitmapFrameMetadata;   
 51   
 52        
 53   
 54               if (bitmapFrame != null)   
 55   
 56               {   
 57   
 58                   //   
 59   
 60                   // now get an InPlaceBitmapMetadataWriter, modify the metadata and try to save   
 61   
 62                   //   
 63   
 64                   InPlaceBitmapMetadataWriter writer = bitmapFrameCreateInPlaceBitmapMetadataWriter();   
 65   
 66                   writerSetQuery("/app/ifd/exif:{uint=}"":: ::");   
 67   
 68                   if (!writerTrySave() == true)   
 69   
 70                   {   
 71   
 72                       //   
 73   
 74                       // the size of the metadata has been increased and we can't save it   
 75   
 76                       //   
 77   
 78                       uint padding = ;   
 79   
 80        
 81   
 82                       BitmapMetadata metaData = (BitmapMetadata)bitmapFrameMetadataClone();   
 83   
 84                       if (metaData != null)   
 85   
 86                       {   
 87   
 88                           //   
 89   
 90                           // Add padding   
 91   
 92                           //   
 93   
 94                           metaDataSetQuery("/app/ifd/PaddingSchema:Padding", padding);   
 95   
 96                           //   
 97   
 98                           // modify the metadata   
 99   
100                           metaDataSetQuery("/app/ifd/exif:{uint=}"":: ::");   
101   
102                           metaDataSetQuery("/app/ifd/exif:{uint=}"":: ::");   
103   
104                           metaDataSetQuery("/app/ifd/exif:{uint=}"":: ::");   
105   
106                           //   
107   
108                           // get an encoder to create a new jpg file with the addit'l metadata   
109   
110                           //   
111   
112                           JpegBitmapEncoder encoder = new JpegBitmapEncoder();   
113   
114                           encoderFramesAdd(BitmapFrameCreate(bitmapFrame, bitmapFrameThumbnail, metaData, bitmapFrameColorContexts));   
115   
116                           string jpegNewFileName = PathCombine(jpegDirectory, "JpegTempjpg");   
117   
118                           using (Stream jpegStreamOut = FileOpen(jpegNewFileName, FileModeCreateNew, FileAccessReadWrite))   
119   
120                           {   
121   
122                               encoderSave(jpegStreamOut);   
123   
124                           }   
125   
126                           //   
127   
128                           // see if the metadata was really changed   
129   
130                           //   
131   
132                           using (Stream jpegStreamIn = FileOpen(jpegNewFileName, FileModeOpen, FileAccessReadWrite))   
133   
134                           {   
135   
136                               decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptionsPreservePixelFormat, BitmapCacheOptionOnLoad);   
137   
138                               BitmapFrame frame = decoderFrames[];   
139   
140                               BitmapMetadata bmd = (BitmapMetadata)frameMetadata;   
141   
142                               string a = (string)bmdGetQuery("/app/ifd/exif:{uint=}");   
143   
144                               string a = (string)bmdGetQuery("/app/ifd/exif:{uint=}");   
145   
146                               string a = (string)bmdGetQuery("/app/ifd/exif:{uint=}");   
147   
148                           }   
149   
150                       }   
151   
152                   }   
153   
154               }   
155   
156           }   
157   
158       }   
159   
160        

http://www.koders.com/csharp/fid6E5A26A44CC15C401B9D4B4C11EE862ECB6B1D26.aspx?s=Exif.cs#L2

http://www.koders.com/csharp/fid79911D36AE70DCCBB585B72801A5BD591CFCA41E.aspx?s=Exif.cs#L2

代码
  1 //
  2 // Exif.cs : LibExif wrapper for FSpot
  3 //
  4 // Author:
  5 //   Larry Ewing     (lewing@novell.com)
  6 //   Ravi Pratap     (ravi@ximian.com)
  7 //   Miguel de Icaza (miguel@ximian.com)
  8 //
  9 // (C) 2002, 2004, 2005 Novell, Inc.
 10 //
 11 
 12 using System;
 13 using System.Collections;
 14 using System.Runtime.InteropServices;
 15 
 16 using Mono.Unix;
 17 
 18 namespace Exif {
 19     public enum Tag {
 20         InteroperabilityIndex        = 0x0001,
 21         InteroperabilityVersion            = 0x0002,
 22         ImageWidth             = 0x0100,
 23         ImageHeight             = 0x0101,
 24         BitsPersample                  = 0x0102,
 25         Compression             = 0x0103,
 26         PhotometricInterpretation     = 0x0106,
 27         FillOrder             = 0x010a,
 28         DocumentName             = 0x010d,
 29         ImageDescription         = 0x010e,
 30         Make                 = 0x010f,
 31         Model                 = 0x0110,
 32         StripOffsets             = 0x0111,
 33         Orientation             = 0x0112,
 34         SamplesPerPixel         = 0x0115,
 35         RowsPerStrip            = 0x0116,
 36         StripByteCounts         = 0x0117,
 37         XResolution             = 0x011a,
 38         YResolution             = 0x011b,
 39         PlanarConfiguration         = 0x011c,
 40         ResolutionUnit          = 0x0128,
 41         TransferFunction         = 0x012d,
 42         Software             = 0x0131,
 43         DateTime            = 0x0132,
 44         Artist                = 0x013b,
 45         WhitePoint            = 0x013e,
 46         PrimaryChromaticities        = 0x013f,
 47         TransferRange            = 0x0156,
 48         JPEGProc            = 0x0200,
 49         JPEGInterchangeFormat            = 0x0201,
 50         JPEGInterchangeFormatLength    = 0x0202,
 51         YCBCRCoefficients        = 0x0211,
 52         YCBCRSubSampling        = 0x0212,
 53         YCBCRPositioning        = 0x0213,
 54         ReferenceBlackWhite        = 0x0214,
 55         RelatedImageFileFormat       = 0x1000,
 56         RelatedImageWidth        = 0x1001,
 57         RelatedImageHeight        = 0x1002,
 58         CFARepeatPatternDim        = 0x828d,
 59         CFAPattern            = 0x828e,
 60         BatteryLevel            = 0x828f,
 61         Copyright            = 0x8298,
 62         ExposureTime            = 0x829a,
 63         FNumber             = 0x829d,
 64         IPTCNAA                    = 0x83bb,
 65         ExifIfdPointer              = 0x8769,
 66         InterColorProfile        = 0x8773,
 67         ExposureProgram         = 0x8822,
 68         SpectralSensitivity        = 0x8824,
 69         GPSInfoIfdPointer        = 0x8825,
 70         ISOSpeedRatings                = 0x8827,
 71         OECF                = 0x8828,
 72         ExifVersion            = 0x9000,
 73         DateTimeOriginal        = 0x9003,
 74         DateTimeDigitized        = 0x9004,
 75         ComponentsConfiguration            = 0x9101,
 76         CompressedBitsPerPixel            = 0x9102,
 77         ShutterSpeedValue        = 0x9201,
 78         ApertureValue            = 0x9202,
 79         BrightnessValue          = 0x9203,
 80         ExposureBiasValue        = 0x9204,
 81         MaxApertureValue        = 0x9205,
 82         SubjectDistance         = 0x9206,
 83         MeteringMode            = 0x9207,
 84         LightSource            = 0x9208,
 85         Flash                = 0x9209,
 86         FocalLength            = 0x920a,
 87         SubjectArea            = 0x9214,
 88         MakerNote            = 0x927c,
 89         UserComment            = 0x9286,
 90         SubSecTime            = 0x9290,
 91         SubSecTimeOriginal        = 0x9291,
 92         SubSecTimeDigitized        = 0x9292,
 93         FlashPixVersion         = 0xa000,
 94         ColorSpace            = 0xa001,
 95         PixelXDimension         = 0xa002,
 96         PixelYDimension         = 0xa003,
 97         RelatedSoundFile        = 0xa004,
 98         InteroperabilityIfdPointer    = 0xa005,
 99         FlashEnergy            = 0xa20b,
100         SpatialFrequencyResponse    = 0xa20c,
101         FocalPlaneXResolution            = 0xa20e,
102         FocalPlaneYResolution            = 0xa20f,
103         FocalPlaneResolutionUnit    = 0xa210,
104         SubjectLocation         = 0xa214,
105         ExposureIndex            = 0xa215,
106         SensingMethod            = 0xa217,
107         FileSource            = 0xa300,
108         SceneType            = 0xa301,
109         NewCFAPattern                = 0xa302,
110         CustomRendered          = 0xa401,
111         ExposureMode            = 0xa402,
112         WhiteBalance            = 0xa403,
113         DigitalZoomRatio        = 0xa404,
114         FocalLengthIn35mmFilm            = 0xa405,
115         SceneCaptureType        = 0xa406,
116         GainControl            = 0xa407,
117         Contrast            = 0xa408,
118         Saturation            = 0xa409,
119         Sharpness            = 0xa40a,
120         DeviceSettingDescription    = 0xa40b,
121         SubjectDistanceRange        = 0xa40c,
122         ImageUniqueId           = 0xa420,
123 
124         // The Following IDs are not described the EXIF spec
125 
126         // The XMP spec declares that XMP data should live 0x2bc when
127         // embedded in tiff images.
128         XMP                             = 0x02bc,
129         
130         // Print Image Matching data
131         PimIfdPointer              = 0xc4a5
132     }
133     
134     public enum ByteOrder {
135         Motorola,
136         Intel
137     }
138     
139     public enum ExifFormat {
140         Byte      = 1,
141         Ascii     = 2,
142         Short     = 3,
143         Long      = 4,
144         Rational  = 5,
145         Undefined = 7,
146         Slong     = 9,
147         SRational = 10
148     }
149     
150     public enum Ifd {
151         Zero = 0,
152         One,
153         Exif,
154         Gps,
155         InterOperability,
156         Count
157     }
158     
159     internal class ExifUtil {
160         
161         [DllImport ("libexif.dll")]
162         static extern IntPtr exif_tag_get_name (Tag tag);
163         
164         [DllImport ("libexif.dll")]
165         static extern IntPtr exif_tag_get_title (Tag tag);
166         
167         [DllImport ("libexif.dll")]
168         static extern IntPtr exif_tag_get_description (Tag tag);
169         
170         [DllImport ("libexif.dll")]
171         static extern IntPtr exif_byte_order_get_name (ByteOrder order);
172         
173         [DllImport ("libexif.dll")]
174         static extern IntPtr exif_format_get_name (ExifFormat format);
175         
176         [DllImport ("libexif.dll")]
177         static extern char exif_format_get_size (ExifFormat format);
178         
179         [DllImport ("libexif.dll")]
180         static extern IntPtr exif_ifd_get_name (Ifd ifd);
181         
182         public static string GetTagName (Tag tag)
183         {
184             
185             IntPtr raw_ret = exif_tag_get_name (tag);
186             return Marshal.PtrToStringAnsi (raw_ret);
187         }
188         
189         public static string GetTagTitle (Tag tag)
190         {
191             IntPtr raw_ret = exif_tag_get_title (tag);
192             return Marshal.PtrToStringAnsi (raw_ret);
193         }
194         
195         public static string GetTagDescription (Tag tag)
196         {
197             IntPtr raw_ret = exif_tag_get_description (tag);
198             return Marshal.PtrToStringAnsi (raw_ret);
199         }
200         
201         public static string GetByteOrderName (ByteOrder order)
202         {
203             IntPtr raw_ret = exif_byte_order_get_name (order);
204             return Marshal.PtrToStringAnsi (raw_ret);
205         }
206         
207         public static string GetFormatName (ExifFormat format)
208         {
209             IntPtr raw_ret = exif_format_get_name (format);
210             return Marshal.PtrToStringAnsi (raw_ret);
211         }
212         
213         public static char GetFormatSize (ExifFormat format)
214         {
215             return exif_format_get_size (format);
216         }
217         
218         public static string GetIfdName (Ifd ifd)
219         {            
220             IntPtr raw_ret = exif_ifd_get_name (ifd);
221             return Marshal.PtrToStringAnsi (raw_ret);
222         }
223         
224         public static string GetIfdNameExtended (Ifd ifd)
225         {
226             switch (ifd) {
227             case Ifd.Zero:
228                 return Catalog.GetString ("Image Directory");
229             case Ifd.One:
230                 return Catalog.GetString ("Thumbnail Directory");
231             case Ifd.Exif:
232                 return Catalog.GetString ("Exif Directory");
233             case Ifd.Gps:
234                 return Catalog.GetString ("GPS Directory");
235             case Ifd.InterOperability:
236                 return Catalog.GetString ("InterOperability Directory");
237             default:
238                 return Catalog.GetString ("Unknown Directory");
239             }
240         }
241         
242         public static DateTime DateTimeFromString(string dt)
243         {
244             // Exif DateTime strings are formatted as
245             //      "YYYY:MM:DD HH:MM:SS"
246             
247             string delimiters = " :";
248             string[] dt_data = dt.Split ( delimiters.ToCharArray(), 6 );
249             DateTime result;
250             result = new DateTime (Int32.Parse(dt_data[0]), Int32.Parse(dt_data[1]), Int32.Parse(dt_data[2]),
251                            Int32.Parse(dt_data[3]), Int32.Parse(dt_data[4]), Int32.Parse(dt_data[5]));
252             
253             return result;
254         }    
255         
256     }        
257 
258     public abstract class ExifObject : IDisposable {
259         protected HandleRef handle;
260         
261         public HandleRef Handle {
262             get {
263                 return handle;
264             }
265         }
266         
267         public ExifObject () {}
268 
269         public ExifObject (IntPtr ptr)
270         {
271             handle = new HandleRef (this, ptr);
272         }
273         
274         protected abstract void Cleanup ();
275         
276         public void Dispose () {
277             Cleanup ();
278             System.GC.SuppressFinalize (this);
279         }
280         
281         ~ExifObject ()
282         {
283             Cleanup ();
284         }
285     }
286     
287     [StructLayout(LayoutKind.Sequential)]
288     internal unsafe struct _ExifContent {
289         public IntPtr entries;
290         public uint count; 
291         public IntPtr parent;
292         
293         public IntPtr priv;
294     }
295     
296     public class ExifContent : ExifObject {
297         ExifData parent;
298         public ExifData Parent {
299             get {
300                 return parent;
301             }
302         }
303 
304         System.Collections.ArrayList entries;
305         
306         internal ExifContent (ExifData parent, IntPtr handle) : base (handle)
307         {
308             this.parent = parent;
309             exif_content_ref (this.handle);
310         }
311         
312         [DllImport ("libexif.dll")]
313         static extern void exif_content_ref (HandleRef handle);
314         
315         [DllImport ("libexif.dll")]
316         static extern void exif_content_unref (HandleRef handle);
317         
318         protected override void Cleanup ()
319         {
320             exif_content_unref (handle);
321         }
322         
323         [DllImport ("libexif.dll")]
324         internal static extern void exif_content_remove_entry (HandleRef content, HandleRef entry);
325         
326         [DllImport ("libexif.dll")]
327         internal static extern void exif_content_add_entry (HandleRef content, HandleRef entry);
328         
329         public ExifEntry Lookup (Tag tag)
330         {
331             Assemble ();
332             
333             foreach (ExifEntry entry in entries) {
334                 if (entry.Tag == tag) {
335                     return entry;
336                 }
337             }        
338             
339             return null;
340         }
341 
342         public bool Contains (ExifEntry entry)
343         {
344             Assemble ();
345 
346             return entries.Contains (entry);
347         }
348 
349         public ExifEntry GetEntry (Tag tag)
350         {
351             Assemble ();
352             
353             ExifEntry entry = Lookup (tag);
354             if (entry == null)
355                 entry = new ExifEntry (this, tag);
356 
357             return entry;
358         }
359 
360         public void Add (ExifEntry entry)
361         {
362             Assemble ();
363 
364             entries.Add (entry);
365             // This call can recurse into this function but it protects
366             // itself by checking if it the content already contains the entry
367             entry.SetParent (this);
368             exif_content_add_entry (this.handle, entry.Handle);    
369         }
370 
371         public void Remove (ExifEntry entry)
372         {
373             Assemble ();
374             
375             entries.Remove (entry);
376             // This call can recurse into this function but it protects
377             // itself by checking if it the content already contains the entry
378             entry.SetParent (null);
379             exif_content_remove_entry (this.handle, entry.Handle);
380         }
381         
382         public ExifEntry [] GetEntries () 
383         {
384             Assemble ();
385 
386             return (ExifEntry [])entries.ToArray (typeof (ExifEntry));
387         }
388         
389         [DllImport ("libexif.dll")]
390         internal static unsafe extern IntPtr exif_content_foreach_entry (HandleRef content,
391                                          ExifContentForeachEntryFunc func,
392                                          IntPtr data);
393         
394         internal delegate void ExifContentForeachEntryFunc (IntPtr entry_ptr, IntPtr data);
395         
396             void AssembleEntry (IntPtr entry, IntPtr data)
397         {
398             entries.Add (new ExifEntry (this, entry));
399         }
400         
401         ExifContentForeachEntryFunc func;
402         
403         public void  Assemble ()
404         {
405             if (entries == null) {
406                     entries = new System.Collections.ArrayList ();
407                     
408                     func = new ExifContentForeachEntryFunc (AssembleEntry);
409                     exif_content_foreach_entry (this.Handle, func, IntPtr.Zero);
410             }
411         }
412     }
413     
414     
415     [StructLayout(LayoutKind.Sequential)]
416     internal struct _ExifEntry {
417         public Tag tag;
418         public int format;
419         public uint components;
420         public IntPtr data;
421         public uint  size;
422         
423         public IntPtr parent;
424         
425         public IntPtr priv;
426     }
427     
428     
429     public class ExifEntry : ExifObject {
430         ExifContent parent;
431         public ExifContent Parent {
432             get {
433                 unsafe {
434                     if (_handle->parent != parent.Handle.Handle)
435                         throw new Exception ("Invalid Object State");
436                     
437                     return parent;
438                 }
439             }
440         }
441         // Don't use this unless you know exactly what you are doing
442         internal void SetParent (ExifContent adoptor) {
443             // NOTE this api is ugly but the check prevent the parent state 
444             // from getting confused.  See ExifContent Add and Remove for the 
445             // other half.
446             if (parent != null && parent.Contains (this))
447                 parent.Remove (this);
448 
449             if (adoptor != null && !adoptor.Contains (this))
450                 adoptor.Add (this);
451             
452             parent = adoptor;
453         }
454 
455         internal ExifEntry (ExifContent parent, IntPtr native) : base (native)
456         {
457             this.handle = new HandleRef (this, native);
458             this.parent = parent;
459             exif_entry_ref (this.handle);
460         }
461 
462         [DllImport ("libexif.dll")]
463         internal static extern IntPtr exif_entry_new ();
464 
465         [DllImport ("libexif.dll")]
466         internal static extern void exif_entry_initialize (HandleRef handle, Tag tag);
467 
468         public ExifEntry (ExifContent parent, Tag tag)
469         {
470             handle = new HandleRef (this, exif_entry_new ());
471             parent.Add (this);
472             this.Reset (tag);
473         }
474         
475         public void Reset (Tag tag)
476         {
477             unsafe {
478                 // Free any exsting data so that _initialize will actually set the data
479                 if (_handle->data != IntPtr.Zero)
480                     ExifData.free (_handle->data);
481                 _handle->data = IntPtr.Zero;
482             }
483 
484             exif_entry_initialize (handle, tag);
485 
486             //FIXME the month string in time fields in libexif ix currently broken so we do our own. 
487             if (tag == Tag.DateTime
488                 || tag == Tag.DateTimeOriginal
489                 || tag == Tag.DateTimeDigitized)
490                 this.SetData (System.DateTime.Now);
491 
492         }
493 
494 
495         public void Reset ()
496         {
497             Reset (Tag);
498         }
499 
500         protected override void Cleanup ()
501         {
502             exif_entry_unref (this.handle);
503         }
504         
505         private unsafe _ExifEntry *_handle {
506             get {
507                     return (_ExifEntry *)handle.Handle;
508             }
509         }
510         
511         public Tag Tag {
512             get {
513                 unsafe {
514                     return _handle->tag;
515                 }
516             }
517         }
518         
519         public ExifFormat Format {
520             get {
521                 unsafe {
522                     return (ExifFormat) _handle->format;
523                 }
524             }
525         }
526         
527         public byte [] Data {
528             get {
529                 unsafe {
530                     byte [] data = new byte [_handle->size]; 
531                     
532                     if (data.Length > 0)
533                         Marshal.Copy (_handle->data, data, 0, (int)_handle->size);
534                     
535                     return data;
536                 }
537             }
538         }
539         
540         public void SetData (byte [] data, int size)
541         {
542             unsafe {
543                 if (data == null || data.Length == 0)
544                     throw new System.Exception ("Invalid Length");
545                 
546                 if (_handle->data != IntPtr.Zero)
547                     ExifData.free (_handle->data);
548                 
549                 _handle->data = ExifData.malloc ((uint)data.Length);
550                 Marshal.Copy (data, 0, _handle->data, data.Length);
551 
552                 _handle->size = (uint) data.Length;
553                 // This needs to be set per type as well but
554                 // we do it here as well
555                 _handle->components = (uint) (data.Length / size);
556             }
557         }
558         
559         public void SetData (byte []data)
560         {
561             SetData (data, 1);
562         }
563 
564         public void SetData (uint s)
565         {
566             this.SetData (FSpot.BitConverter.GetBytes (s, this.ByteOrder == ByteOrder.Intel), 4);
567         }
568 
569         public void SetData (ushort s)
570         {
571             this.SetData (FSpot.BitConverter.GetBytes (s, this.ByteOrder == ByteOrder.Intel), 2);
572         }        
573 
574         public void SetData (string value)
575         {
576             int len = System.Text.Encoding.UTF8.GetByteCount (value);
577             byte [] tmp = new byte [len + 1];
578             System.Text.Encoding.UTF8.GetBytes (value, 0, value.Length, tmp, 0);
579             tmp[len] = 0;
580             System.Console.WriteLine ("value = {0} len = {1}", value, len);
581             SetData (tmp, 1);
582         }
583 
584         public void SetData (System.DateTime time)
585         {
586             SetData (time.ToString ("yyyy:MM:dd HH:mm:ss"));
587         }
588         
589         private unsafe void PutBytes (byte *dest, byte *src, int count)
590         {
591             int i = 0;
592             if (System.BitConverter.IsLittleEndian == (this.ByteOrder == ByteOrder.Intel)) {
593                 for (i = 0; i < count; i++) {
594                     //System.Console.WriteLine ("Copying normal byte [{0}]= {1}", i, src[i]);
595                     dest [i] = src [i];
596                 }
597             } else {
598                 for (i = 0; i < count; i++) {
599                     //System.Console.WriteLine ("Copying swapped byte [{0}]= {1}", i, src[i]);
600                     dest [i] = src [count - i -1];  
601                 }
602             }
603         }
604         
605         private unsafe uint ToUInt (byte *src)
606         {
607             uint value;
608             PutBytes ((byte *)&value, (byte *)src, 4);
609             return value;
610         }
611         
612         private unsafe ushort ToUShort (byte *src)
613         {
614             ushort value;
615             PutBytes ((byte *)&value, (byte *)src, 2);
616             return value;
617         }
618         
619         public uint [] GetDataUInt () {
620             unsafe {
621                 uint [] result = new uint [_handle->components];
622                 uint *src = (uint *)_handle->data;
623                 //System.Console.WriteLine ("copying {0} components", result.Length); 
624                 for (int i = 0; i < result.Length; i++) {
625                     result [i] = ToUInt ((byte *)src);
626                     //System.Console.WriteLine ("value[{0}] = {1}", i, result [i]);
627                     src += i;
628                 }
629                 
630                 return result;
631             }
632         }            
633 
634         public ushort [] GetDataUShort () {
635             unsafe {
636                 ushort [] result = new ushort [_handle->components];
637                 ushort *src = (ushort *)_handle->data;
638                 //System.Console.WriteLine ("copying {0} components", result.Length); 
639                 for (int i = 0; i < result.Length; i++) {
640                     result [i] = ToUShort ((byte *)src);
641                     //System.Console.WriteLine ("value[{0}] = {1}", i, result [i]);
642                     src += i;
643                 }
644                 
645                 return result;
646             }
647         }
648 
649 
650         public int [] GetDataInt () {
651             return null;
652         }
653 
654         public ByteOrder ByteOrder
655         {
656             get {
657                 return parent.Parent.GetByteOrder ();
658             }
659         }
660 
661         public string Description 
662         {
663             get {
664                 return ExifUtil.GetTagDescription (Tag);
665             }
666         }
667         
668         public string Name
669         {
670             get {
671                 return ExifUtil.GetTagName (Tag);
672             }
673         }
674         
675         public string Title
676         {
677             get {
678                 return ExifUtil.GetTagTitle (Tag);
679             }
680         }
681         
682         static int fallback = 0;
683         
684         // FIXME this version is only valid in libexif 0.5
685         [DllImport ("libexif.dll")]
686         internal static extern IntPtr exif_entry_get_value (HandleRef handle);
687         [DllImport ("libexif.dll")]
688         internal static extern IntPtr exif_entry_get_value_brief (HandleRef handle);
689         
690         // FIXME this version is only valid in libexif 0.6
691         [DllImport ("libexif.dll")]
692         internal static extern IntPtr exif_entry_get_value (HandleRef handle, byte  [] value, int maxlen);
693         
694         public string Value
695         {
696             get {
697                 if (fallback == 0) {
698                     try {
699                         exif_entry_get_value_brief (this.Handle);
700                         fallback = 1;
701                     } catch (EntryPointNotFoundException) {
702                         fallback = -1;
703                     }
704                 }
705                 
706                 if (fallback > 0
707                     return Marshal.PtrToStringAnsi (exif_entry_get_value (this.Handle));
708                 else {
709                     byte [] value = new byte [1024];
710                     exif_entry_get_value (this.Handle, value, value.Length);
711 
712                     int i;
713                     for (i = 0; i <  value.Length; i++) {
714                         if (value [i] == 0
715                             break;
716                     }
717                     int len = System.Math.Max (i, 0);
718                     if (len == 0)
719                         return null;
720                     
721                     return System.Text.Encoding.UTF8.GetString (value, 0, len);
722                 }
723             }
724         }
725         
726         [DllImport ("libexif.dll")]
727         internal static extern void exif_entry_ref (HandleRef handle);
728         
729         [DllImport ("libexif.dll")]
730         internal static extern void exif_entry_unref (HandleRef handle);
731     }
732     
733     [StructLayout(LayoutKind.Sequential)]
734     internal struct _ExifData {
735         internal IntPtr ifd0;
736         internal IntPtr ifd1;
737         internal IntPtr ifd_exif;
738         internal IntPtr ifd_gps;
739         internal IntPtr ifd_interop;
740 
741         internal IntPtr  data;
742         internal int     size;
743         
744         internal IntPtr priv;
745     }
746     
747     public class ExifData : ExifObject {
748         System.Collections.ArrayList ifds;
749         
750         [DllImport ("libexif.dll")]
751         internal static extern IntPtr exif_data_new ();
752         
753         public ExifData ()
754         {
755             handle = new HandleRef (this, exif_data_new ());
756         }
757         
758         [DllImport ("libexif.dll")]
759         internal static extern IntPtr exif_data_new_from_file (string path);
760             
761         public ExifData (string filename)
762         {
763             handle = new HandleRef (this, exif_data_new_from_file (filename));
764         }
765         
766         [DllImport ("libexif.dll")]
767         internal static extern IntPtr exif_data_new_from_data (byte [] data, uint size);
768 
769         public ExifData (byte [] data)
770         {
771             handle = new HandleRef (this, exif_data_new_from_data (data, (uint) data.Length));
772         }
773 
774         public ExifData (byte [] data, uint size)
775         {
776             handle = new HandleRef (this, exif_data_new_from_data (data, size));
777         }
778 
779         [DllImport ("libc")] 
780         internal static extern void free (IntPtr address);
781         
782         [DllImport ("libc")] 
783         internal static extern IntPtr malloc (uint size);
784         
785         [DllImport ("libexif.dll")]
786         private static extern void exif_data_save_data (HandleRef handle, out IntPtr content, out uint size);        
787         public byte [] Save ()
788         {
789             Byte [] content = null;
790             uint size;
791             IntPtr data;
792             unsafe {
793                 exif_data_save_data (handle, out data, out size);
794                 
795                 content = new byte [size];
796                 Marshal.Copy (data, content, 0, (int)size);
797                 free (data);
798             }
799                 
800             System.Console.WriteLine ("Saved {0} bytes", content.Length);
801             return content;
802         }
803         
804         [DllImport ("libexif.dll")]
805         internal static extern void exif_data_unref (HandleRef data);
806         
807         [DllImport ("libexif.dll")]
808         internal static extern void exif_data_free (HandleRef data);
809 
810         protected override void Cleanup ()
811         {
812             exif_data_unref (handle);
813         }
814         
815         [DllImport ("libexif.dll")]
816         internal static extern void exif_data_dump (HandleRef data);
817 
818         public void Dump ()
819         {
820             exif_data_dump (handle);
821         }
822         
823         public ExifContent GetContents (Ifd ifd)
824         {
825             Assemble ();
826 
827             return (ExifContent) ifds [(int)ifd];
828         }
829 
830         public ExifContent [] GetContents ()
831         {
832             Assemble ();
833 
834             return (ExifContent []) ifds.ToArray (typeof (ExifContent));
835         }
836 
837         [DllImport("libexif.dll")]
838         internal static extern ByteOrder exif_data_get_byte_order (HandleRef handle);
839         
840         public ByteOrder GetByteOrder ()
841         {
842             return exif_data_get_byte_order (handle);
843         }
844         
845         internal delegate void ExifDataForeachContentFunc (IntPtr content, IntPtr data);
846         
847         [DllImport ("libexif.dll")]
848         internal unsafe static extern void exif_data_foreach_content(HandleRef handle, ExifDataForeachContentFunc func, IntPtr data);
849         
850         unsafe void AssembleIfds (IntPtr content, IntPtr data)
851         {
852             ifds.Add (new ExifContent (this, content));
853         }
854         
855         public ExifEntry LookupFirst (Tag tag)
856         {
857             Assemble ();
858             foreach (ExifContent content in ifds) {
859                 if (content == null)
860                     continue;
861                 
862                 ExifEntry entry = content.Lookup (tag);
863                 if (entry != null)
864                     return entry;
865             }
866             return null;
867         }
868 
869         public string LookupFirstValue (Tag tag)
870         {
871             ExifEntry entry = LookupFirst (tag);
872             if (entry != null) {
873                 return entry.Value;
874             }
875             return null;
876         }
877 
878         public void Assemble ()
879         {
880             if (ifds == null) {
881                 ifds = new System.Collections.ArrayList ();
882 
883                 if (handle.Handle != IntPtr.Zero)
884                     exif_data_foreach_content (handle, new ExifDataForeachContentFunc (AssembleIfds), IntPtr.Zero);
885             }
886         }
887         
888         byte [] empty = new byte [0];
889         public byte [] Data {
890             get {
891                 unsafe {
892                     _ExifData * obj = (_ExifData *) Handle.Handle;
893                     byte [] result;
894                     
895                     if (obj == null || obj->data == (IntPtr) 0)
896                         result = empty;
897                     else {
898                         result = new byte [obj->size];
899                         Marshal.Copy (obj->data, result, 0, obj->size);
900                         
901                     }
902                     return result;
903                 }
904             }
905             set {
906                 unsafe {
907                     _ExifData * obj = (_ExifData *) Handle.Handle;
908                     if (value.Length > 65533)
909                         throw new System.Exception ("Thumbnail too large");
910                     
911                     if (obj->data != IntPtr.Zero)
912                         free (obj->data);
913                     
914                     obj->data = malloc ((uint)value.Length);
915                     Marshal.Copy (value, 0, obj->data, value.Length);
916                 }
917             }
918         }
919     }
920 }
921 
原文地址:https://www.cnblogs.com/geovindu/p/1936339.html