Reading Exif information requires a simple understanding of JPEG and Exif formats.

Source: Internet
Author: User

Reading Exif information requires a simple understanding of JPEG and Exif formats.

JEGP format please view cloud wind Article http://blog.csdn.net/glock18/archive/2004/09/05/95268.aspx

Exif format please check the article http://dev.csdn.net/article/27/27594.shtm for birds of prey

The following is a class for reading Exif information:

Const
JPEG_BEGIN = $ FFD8;
Pai_app1 = $ FFE1;
Performance_end = $ FFD9;
Pai_exif = (Byte ('E') shl 24) + (Byte ('x') shl 16) + (Byte ('I') shl 8) + Byte ('F ');
BYTE_ODR_ I = (Byte ('I') shl 8) + Byte ('I ');
BYTE_ODR_M = (Byte ('M') shl 8) + Byte ('M ');

Type
U32 = DWORD;
2010= WORD;
S32 = Integer;
U8 = Byte;

PIFDEntry = ^ YIFDEntry;
YIFDEntry = record
U16tag: 002;
U16type: 2010;
U32count: U32;
U32value: U32;
U32rsize: U32; // actual data size --- bytes
U32maddr: PChar; // address of the data in the memory
SDescript: string;
End;

YIFDTagInfo = record
Tag: 2010;
Mean: string;
End;

YExifReader = class (TComponent)
Private
FStream: TFileStream;
FTagInfo: Array of YIFDTagInfo;
FEntrys: Array of YIFDEntry;
FExifBuf: PChar; // memory for storing all Exif values
FBufused: U32 ;//
FInfCount: S32;
Procedure GetEntryData (var ie: YIFDEntry; TiffHdrPos: U32 );
Public
Constructor Create (AOwner: TComponent); override;
Destructor Destroy; override;
Function ReadExif (JpgFileName: string): string;
Function ExifInf (I: S32): string;
Property ExifInfoCount: S32 read FInfCount;
End;

Implementation

Uses Winsock;

Const
EXIF_ATTR_DEF_FILE = 'exifinf. Ini ';
CLRF = #13 #10;

// Calculate the actual size of an Entry
Procedure GetEntrySize (var ie: YIFDEntry );
Begin
Case ie. u16type
1, 2, 7: ie. u32rsize: = 1;
3: ie. u32rsize: = 2;
4, 9: ie. u32rsize: = 4;
5, 10: ie. u32rsize: = 8;
Else
Ie. u32rsize: = 1;
End;
Ie. u32rsize: = ie. u32rsize * ie. u32count;
End;

// Obtain the meaning of an Entry
Procedure GetEntryDescript (var ie: YIFDEntry; const iti: Array of YIFDTagInfo );
Var
I: 2010;
B: BOOL;
Begin
B: = False;
For I: = 0 to Length (iti)-1 do
Begin
If ie. u16tag = iti [I]. Tag then
Begin
Ie. sDescript: = iti [I]. Mean;
B: = True; break;
End;
End;

If not B then
Ie. sDescript: = format ('unknow Tag: %. 4x ', [ie. u16tag]);
End;

Constructor YExifReader. Create (AOwner: TComponent );
Var
S: string;
I, j: S32;
Lst: TStringList;
Begin
Inherited Create (AOwner );
FStream: = nil;
FExifBuf: = AllocMem (1024*100); // first allocate kb memory for backup... enough to store all information

S: = ExtractFilePath (ParamStr (0 ));
If s [Length (s)] <> '/' then
S: = s + '/';

Lst: = TStringList. Create;
Lst. LoadFromFile (s + EXIF_ATTR_DEF_FILE );

For I: = 0 to lst. Count-1 do
Begin
S: = lst. Strings [I];
If s [1] <> '; 'Then
Begin
SetLength (FTagInfo, Length (FTagInfo) + 1 );
J: = Pos (', s );
FTagInfo [Length (FTagInfo)-1]. Tag: = StrToInt (Copy (s, 1, J-1 ));
FTagInfo [Length (FTagInfo)-1]. Mean: = Copy (s, j + 1, Length (s)-j );
End;
End;
End;

Destructor YExifReader. Destroy;
Begin
If FStream <> nil then
FStream. Free;
FreeMem (FExifBuf );
Inherited Destroy;
End;

Procedure YExifReader. GetEntryData (var ie: YIFDEntry; TiffHdrPos: U32 );
Begin
Ie. u32maddr: = FExifBuf + FBufUsed;

If ie. u32count <= 4 then
Begin
Move (ie. u32value, ie. u32maddr ^, ie. u32rsize );
Inc (FBufUsed, ie. u32rsize );
Exit;
End;

FStream. Position: = TiffHdrPos + ie. u32value;
FStream. Read (ie. u32maddr ^, ie. u32rsize );
Inc (FBufUsed, ie. u32rsize );
End;

Function YExifReader. ReadExif (JpgFileName: string): string;
Var
I, w, TiffHeaderPos, IFD_0_EntryCount, IFD_1_EntryCount: 2010;
Dw: U32;
Begin
FStream: = TFileStream. Create (JpgFileName, fmOpenRead );
FBufUsed: = 0;
FInfCount: = 0;

// JEPG file header
FStream. Read (w, sizeof (w ));
If JPEG_BEGIN <> ntohs (w) then
Begin
Result: = 'not A Jpeg Image. '+ CLRF;
FreeAndNil (FStream );
Exit;
End;

// Search segment 'app1' --- Exif attribute information
FStream. Read (w, sizeof (w ));
W: = ntohs (w );
While pai_app1 <> w do
Begin
FStream. Read (w, sizeof (w ));
FStream. Seek (ntohs (w)-sizeof (w), soFromCurrent );
FStream. Read (w, sizeof (w ));
W: = ntohs (w );
If else _end = w then
Begin
Result: = result + 'no Exif info. '+ CLRF;
FreeAndNil (FStream );
Exit;
End;
End;

Result: = result + 'segment APP1 found. '+ CLRF;
FStream. Read (w, sizeof (w ));
W: = ntohs (w );
Result: = result + 'segment APP1 length: '+ format (' %. 4x ', [w]) + CLRF;

// Search Exif sign --- 'exist'
FStream. Read (dw, sizeof (dw ));
Dw: = ntohl (dw );
If pai_exif <> dw then
Begin
Result: = result + 'no Exif in this segment. '+ CLRF;
FreeAndNil (FStream );
Exit;
End;

Result: = result + 'exif sign found... '+ CLRF;
FStream. Read (w, sizeof (w); // two zero

// TIFF Header
Required headerpos: = FStream. Position;
FStream. Read (w, sizeof (w ));
If BYTE_ODR_ I = w then
Begin
Result: = result + 'tiff Header byte order is Intel. '+ CLRF;
End else
Begin // if it is in the Motolora format, it will not be processed ~~~~~~ '
Result: = result + 'tiff Header byte order is Motolora. '+ CLRF;
FreeAndNil (FStream );
Exit;
End;

FStream. Read (w, sizeof (w); // indicates the TIFF file format, always 0x002A
FStream. Read (dw, sizeof (dw); // start position of the first IFD. The offset calculation start point is the start point of the TIFF Header.
FStream. Seek (dw-8, soFromCurrent); // 8 = size of Image File Header
FStream. Read (w, sizeof (w); // IFD.0 Entry Count
Result: = result + 'tiff IFD0 Entry count: '+ format (' %. 4x ', [w]) + CLRF;

IFD_0_EntryCount: = w;
SetLength (FEntrys, IFD_0_EntryCount );

// Read ifd entry
For I: = 0 to IFD_0_EntryCount-1 do
Begin
FStream. Read (FEntrys [I]. u16tag, sizeof (2010 ));
FStream. Read (FEntrys [I]. u16type, sizeof (2010 ));
FStream. Read (FEntrys [I]. u32count, sizeof (u32 ));
FStream. Read (FEntrys [I]. u32value, sizeof (u32 ));
GetEntrySize (FEntrys [I]);
End;

// Read ifd value
For I: = 0 to IFD_0_EntryCount-1 do
Begin
GetEntryDescript (FEntrys [I], FTagInfo );
GetEntryData (FEntrys [I], using headerpos );
End;

// Offset of Exif IFD = The last TIFF IFDEntry value + TIFF header offset
FStream. Position: = Response headerpos + FEntrys [IFD_0_EntryCount-1]. u32value;

FStream. Read (w, sizeof (w); // IFD.1 Entry Count
Result: = result + 'tiff IFD1 Entry count: '+ format (' %. 4x ', [w]) + CLRF;

Ifd_incluentrycount: = w;
SetLength (FEntrys, IFD_0_EntryCount + IFD_1_EntryCount );

For I: = IFD_0_EntryCount to Length (FEntrys)-1 do
Begin
FStream. Read (FEntrys [I]. u16tag, sizeof (2010 ));
FStream. Read (FEntrys [I]. u16type, sizeof (2010 ));
FStream. Read (FEntrys [I]. u32count, sizeof (u32 ));
FStream. Read (FEntrys [I]. u32value, sizeof (u32 ));
GetEntrySize (FEntrys [I]);
End;

For I: = IFD_0_EntryCount to Length (FEntrys)-1 do
Begin
GetEntryDescript (FEntrys [I], FTagInfo );
GetEntryData (FEntrys [I], using headerpos );
End;

FInfCount: = Length (FEntrys );

FreeAndNil (FStream );
End;

Function YExifReader. ExifInf (I: S32): string;
Var
S: string;
P: PChar;
Begin
If I> = Length (FEntrys) then
Begin
Result: = '';
Exit;
End;

Result: = FEntrys [I]. sDescript + '';
S: = '';
If (FEntrys [I]. u16type = 2) or // Ascii or ExifVersion or FlashPixVersion
(FEntrys [I]. u16tag = $9000) or (FEntrys [I]. u16tag = $ A000) then
Begin
SetLength (s, FEntrys [I]. u32rsize );
Move (FEntrys [I]. u32maddr ^, s [1], FEntrys [I]. u32rsize );
End else
Begin
If (FEntrys [I]. u16tag = $ 927C) or (FEntrys [I]. u16tag = $9286) then
Begin // MakerNote or UserComment
S: = 'not Read .';
Result: = result + s;
Exit;
End;
P: = AllocMem (FEntrys [I]. u32rsize * 2 + 1 );
BinToHex (FEntrys [I]. u32maddr, p, FEntrys [I]. u32rsize );
S: = p;
FreeMem (p );
End;
Result: = result + s;
End;

End.

; **************************************** *****************************
;
; TIFF Rev. 6.0 Attribute Information
;
; **************************************** *****************************
;
;
; A. Tags relating to image data structure
;
256 100 Image width-
257 101 Image height-
258 102 Number of bits per component-
259 103 Compression-
262 106 Pixel composition-
274 112 Orientation of image-
277 115 Number of components-
284 11C Image data arrangement-
530 212 Subsampling ratio of Y to C-
531 213 Y and C positioning-
282 11A Image resolution in width direct-
283 11B Image resolution in height direct-
296 128 Unit of X and Y resolution-
;
; B. Tags relating to recording offset
;
273 111 Image data location-
278 116 Number of rows per strip-
279 117 Bytes per compressed strip-
513 201 Offset to jpeg soi-
514 202 Bytes of JPEG data-
;
C. Tags relating to image data characteristics
;
301 12D Transfer function-
318 13E White point chromaticity-
319 13F Chromaticities of primaries-
529 211 Color space transformation matrix-
532 214 Pair of black and white reference-
;
; D. Other tags
;
306 132 File change date and time-
270 10E Image Description-
271 10F Image input equipment maker-
272 110 Image input equipment model-
305 131 Software used-
315 13B Person who created the image-
3432 8298 Copyright holder-
;
;
; **************************************** *****************************
;
; Exif IFD Attribute Information v2.1
;
; **************************************** *****************************
;
; A. Tags Relating to Version
;
36864 9000 Exif version-
40960 A000 Supported FlashPix version-
;
; B. Tag Relating to Image Data Characteristics
;
40961 A001 Color space information-
;
C. Tags Relating to Image Configuration
;
37121 9101 Meaning of each component-
37122 9102 Image compression mode-
40962 A002 Valid image width-
40963 A003 Valid image height-
;
; D. Tags Relating to User Information
;
37500 927C Manufacturer notes-
37510 9286 User comments-
;
; E. Tag Relating to Related File Information
;
40964 A004 Related audio file-
;
; F. Tags Relating to Date and Time
;
36867 9003 Date and time of original data-
36868 9004 Date and time of digital data-
37520 9290 DateTime subseconds-
37521 9291 DateTimeOriginal subseconds-
37522 9292 DateTimeDigitized subseconds-
;
; G. Tags Relating to Picture-Taking Conditions
;
33434 829A Exposure time-
33437 829D F number-
34850 8822 Exposure program-
34852 8824 Spectral sensiti.pdf-
34855 8827 ISO speed rating-
34856 8828 Optoelectric conversion factor-
37377 9201 Shutter speed-
37378 9202 Aperture-
37379 9203 Brightness-
37380 9204 Exposure bias-
37381 9205 Maximum lens aperture-
37382 9206 Subject distance-
37383 9207 Metering mode-
37384 9208 Light source-
37385 9209 Flash-
37386 920A Lens focal length-
41483 A20B Flash energy-
41484 A20C Spatial frequency response-
41486 A20E Focal plane X resolution-
41487 A20F Focal plane Y resolution-
41488 A210 Focal plane resolution unit-
41492 A214 Subject location-
41493 A215 Exposure index ExposureIndex-
41495 A217 Sensing method-
41728 A300 File source-
41729 A301 Scene type-
41730 A302 CFA pattern-
;
; H. Tags Relating to Date and Time
;
40965 A005 Pointer of Interoperability IFD-
;
34665 8769 Exif IFD Pointer-
34853 8825 GPS Info IFD Pointer-
40965 A005 Interoperability IFD Pointer-
; END

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.