1.0.0 • Published 5 years ago

cyexifparser v1.0.0

Weekly downloads
1
License
ISC
Repository
-
Last release
5 years ago

Image EXIF parser that conforms to EXIF V2.3 specifications

This Library is used to extract EXIF information in digital camera image files.

npm

This library is published on npm:

$ npm install --save cyexifparser

Options

OptionTypeDescription
debugBooleanDisplay Debug information when parsing an image
fullDataBooleanGet Full exif data from image with each attribute returining printable, tag, fieldType, values , fieldOffset, fieldLength if true otherwise returning printable and values sub-attributes only
selectedKeysArrayThe array of string containing keys to extrtact from the Exif data alternate to fullData also printable and values sub-attributes only
containsStringThe partial string of keys to extrtact from the Exif data alternate to fullData and selectedKeys also printable and values sub-attributes only

Example usage

One can use the exif parse in many ways

Promise with the parser to an image with exif data, with debug and fulldata on

	var cyexifparser = require("cyexifparser");
	//options to be considered
	var  parserOptions = {
        debug: true,
        fullData: true,
        selectedKeys:['GPS GPSVersionID','GPS GPSTimeStamp'],
        contains: 'GPS'
    };
	var base64Image = "this could be a huge base64 image";// or load data by using nodejs's var fs = require('fs').readFile 
	var data = Buffer.from(base64Image, 'base64');// and pass in the data from fs.readFile's callback function e.g fs.readFile('exif_with_gps.jpg', function (err, data) { .... 
    cyexifparser.CyExifParser(data, parserOptions).then((tags) => {
        console.log(JSON.stringify(tags));
    }).catch((err) => {
        console.error(err);
    });

Callback with the parser to an image with exif data, with debug and fulldata on

	var cyexifparser = require("cyexifparser");
	//options to be considered
	var  parserOptions = {
        debug: true,
        fullData: true,
        selectedKeys:['Image Make','Image Model'],
        contains: 'Thumbnail'
    };
	var base64Image = "this could be a huge base64 image";// or load data by using nodejs's var fs = require('fs').readFile 
	var data = Buffer.from(base64Image, 'base64');// and pass in the data from fs.readFile's callback function e.g fs.readFile('exif_with_gps.jpg', function (err, data) { .... 
    cyexifparser..CyExifParser(data, parserOptions, function (calldata, callerr) {
        if (calldata) {
            console.log(JSON.stringify(calldata));
        } else {
            assert.fail(TestMessage);
        }
    });

Angular Import

One can install the npm module in an anglar component :

import { CyExifParser } from 'cyexifparser';
@Component({
  selector: 'imageexifchecker',
  templateUrl: 'imageexifchecker.html',
})
export class ImageExifChecker {
 ......
  base64toBlob(base64Data, contentType = '', sliceSize = 512) {
    base64Data = base64Data.replace(/^data\:([^\;]+)\;base64,/gmi, '');
    var byteCharacters = atob(base64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        for (var i = 0; i < slice.length; ++i) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        var byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }

    var blob = new Blob(byteArrays, { type: contentType });
    return blob;
  }

  hasExif(base64Image) {
    var blobImg = this.base64ToArrayBuffer(base64Image);
    CyExifParser(blobImg, 
                        { 
                          debug: false, 
                          fullData: false ,
                          selectedKeys:['GPS GPSLongitude','GPS GPSLatitude'],
                          contains: 'GPS'
                        }
                ).then((tags) => {
      this.imageData[imgId].exif = tags;
      let taghasgps = tags.hasOwnProperty('GPS GPSLongitude') && tags.hasOwnProperty('GPS GPSLatitude');
      if (taghasgps) {
        console.log("Latitude : " + tags['GPS GPSLatitude']);
        console.log("Longitude : " + tags['GPS GPSLongitude']);
      }
      console.log(JSON.stringify(tags));
    }).catch((err) => {
      console.log(err.message);
    });
  }
}

Running tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

$ npm install && npm test

Author

Cyril Adelekan twitter

Sample output on a successful extraction of EXIF data

{
  "EXIF ColorSpace": {
    "printable": "Uncalibrated",
    "tag": 40961,
    "fieldType": 3,
    "values": [
      65535
    ],
    "fieldOffset": 442,
    "fieldLength": 2
  },
  "EXIF CompressedBitsPerPixel": {
    "printable": "4",
    "tag": 37122,
    "fieldType": 5,
    "values": [
      4
    ],
    "fieldOffset": 722,
    "fieldLength": 8
  },
  "EXIF Contrast": {
    "printable": "Low",
    "tag": 41992,
    "fieldType": 3,
    "values": [
      1
    ],
    "fieldOffset": 622,
    "fieldLength": 2
  },
  "EXIF CustomRendered": {
    "printable": "Normal process",
    "tag": 41985,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 538,
    "fieldLength": 2
  },
  "EXIF DateTimeDigitized": {
    "printable": "2003:11:23 18:07:37",
    "tag": 36868,
    "fieldType": 2,
    "values": "2003:11:23 18:07:37",
    "fieldOffset": 702,
    "fieldLength": 20
  },
  "EXIF DateTimeOriginal": {
    "printable": "2003:11:23 18:07:37",
    "tag": 36867,
    "fieldType": 2,
    "values": "2003:11:23 18:07:37",
    "fieldOffset": 682,
    "fieldLength": 20
  },
  "EXIF DigitalZoomRatio": {
    "printable": "1",
    "tag": 41988,
    "fieldType": 5,
    "values": [
      1
    ],
    "fieldOffset": 812,
    "fieldLength": 8
  },
  "EXIF ExifImageLength": {
    "printable": "375",
    "tag": 40963,
    "fieldType": 4,
    "values": [
      375
    ],
    "fieldOffset": 466,
    "fieldLength": 4
  },
  "EXIF ExifImageWidth": {
    "printable": "500",
    "tag": 40962,
    "fieldType": 4,
    "values": [
      500
    ],
    "fieldOffset": 454,
    "fieldLength": 4
  },
  "EXIF ExifVersion": {
    "printable": "0,2,2,0",
    "tag": 36864,
    "fieldType": 7,
    "values": [
      48,
      50,
      50,
      48
    ],
    "fieldOffset": 262,
    "fieldLength": 4
  },
  "EXIF ExposureBiasValue": {
    "printable": "0",
    "tag": 37380,
    "fieldType": 10,
    "values": [
      0
    ],
    "fieldOffset": 730,
    "fieldLength": 8
  },
  "EXIF ExposureMode": {
    "printable": "Auto exposure",
    "tag": 41986,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 550,
    "fieldLength": 2
  },
  "EXIF ExposureProgram": {
    "printable": "Aperture-priority AE",
    "tag": 34850,
    "fieldType": 3,
    "values": [
      3
    ],
    "fieldOffset": 250,
    "fieldLength": 2
  },
  "EXIF ExposureTime": {
    "printable": "1/125",
    "tag": 33434,
    "fieldType": 5,
    "values": [
      "1/125"
    ],
    "fieldOffset": 666,
    "fieldLength": 8
  },
  "EXIF FNumber": {
    "printable": "9/2",
    "tag": 33437,
    "fieldType": 5,
    "values": [
      "9/2"
    ],
    "fieldOffset": 674,
    "fieldLength": 8
  },
  "EXIF FileSource": {
    "printable": "Digital Camera",
    "tag": 41728,
    "fieldType": 7,
    "values": [
      3
    ],
    "fieldOffset": 502,
    "fieldLength": 1
  },
  "EXIF Flash": {
    "printable": "No",
    "tag": 37385,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 358,
    "fieldLength": 2
  },
  "EXIF FlashPixVersion": {
    "printable": "0,1,0,0",
    "tag": 40960,
    "fieldType": 7,
    "values": [
      48,
      49,
      48,
      48
    ],
    "fieldOffset": 430,
    "fieldLength": 4
  },
  "EXIF FocalLength": {
    "printable": "2333/100",
    "tag": 37386,
    "fieldType": 5,
    "values": [
      "2333/100"
    ],
    "fieldOffset": 746,
    "fieldLength": 8
  },
  "EXIF FocalLengthIn35mmFormat": {
    "printable": "35",
    "tag": 41989,
    "fieldType": 3,
    "values": [
      35
    ],
    "fieldOffset": 586,
    "fieldLength": 2
  },
  "EXIF GainControl": {
    "printable": "Low gain up",
    "tag": 41991,
    "fieldType": 3,
    "values": [
      1
    ],
    "fieldOffset": 610,
    "fieldLength": 2
  },
  "EXIF LightSource": {
    "printable": "Unknown",
    "tag": 37384,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 346,
    "fieldLength": 2
  },
  "EXIF MaxApertureValue": {
    "printable": "3",
    "tag": 37381,
    "fieldType": 5,
    "values": [
      3
    ],
    "fieldOffset": 738,
    "fieldLength": 8
  },
  "EXIF MeteringMode": {
    "printable": "Spot",
    "tag": 37383,
    "fieldType": 3,
    "values": [
      3
    ],
    "fieldOffset": 334,
    "fieldLength": 2
  },
  "EXIF RelatedSoundFile": {
    "printable": "            ",
    "tag": 40964,
    "fieldType": 2,
    "values": "            ",
    "fieldOffset": 790,
    "fieldLength": 13
  },
  "EXIF Saturation": {
    "printable": "Normal",
    "tag": 41993,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 634,
    "fieldLength": 2
  },
  "EXIF SceneCaptureType": {
    "printable": "Standard",
    "tag": 41990,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 598,
    "fieldLength": 2
  },
  "EXIF SceneType": {
    "printable": "Directly Photographed",
    "tag": 41729,
    "fieldType": 7,
    "values": [
      1
    ],
    "fieldOffset": 514,
    "fieldLength": 1
  },
  "EXIF SensingMethod": {
    "printable": "2",
    "tag": 41495,
    "fieldType": 3,
    "values": [
      2
    ],
    "fieldOffset": 490,
    "fieldLength": 2
  },
  "EXIF Sharpness": {
    "printable": "Normal",
    "tag": 41994,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 646,
    "fieldLength": 2
  },
  "EXIF SubSecTime": {
    "printable": "63",
    "tag": 37520,
    "fieldType": 2,
    "values": "63",
    "fieldOffset": 394,
    "fieldLength": 3
  },
  "EXIF SubSecTimeDigitized": {
    "printable": "63",
    "tag": 37522,
    "fieldType": 2,
    "values": "63",
    "fieldOffset": 418,
    "fieldLength": 3
  },
  "EXIF SubSecTimeOriginal": {
    "printable": "63",
    "tag": 37521,
    "fieldType": 2,
    "values": "63",
    "fieldOffset": 406,
    "fieldLength": 3
  },
  "EXIF SubjectDistanceRange": {
    "printable": "Unknown",
    "tag": 41996,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 658,
    "fieldLength": 2
  },
  "EXIF tag 41730": {
    "printable": "0,2,0,2,1,2,0,1",
    "tag": 41730,
    "fieldType": 7,
    "values": [
      0,
      2,
      0,
      2,
      1,
      2,
      0,
      1
    ],
    "fieldOffset": 804,
    "fieldLength": 8
  },
  "EXIF UserComment": {
    "printable": "\u0000,\u0000,\u0000,\u0000,\u0000,\u0000,\u0000,\u0000,t,a,k,e,n, ,a,t, ,b,a,s,i,l,i,c,a, ,o,f, ,c,h,i,n,e,s,e",
    "tag": 37510,
    "fieldType": 7,
    "values": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      116,
      97,
      107,
      101,
      110,
      32,
      97,
      116,
      32,
      98,
      97,
      115,
      105,
      108,
      105,
      99,
      97,
      32,
      111,
      102,
      32,
      99,
      104,
      105,
      110,
      101,
      115,
      101
    ],
    "fieldOffset": 754,
    "fieldLength": 36
  },
  "EXIF WhiteBalance": {
    "printable": "Auto white balance",
    "tag": 41987,
    "fieldType": 3,
    "values": [
      0
    ],
    "fieldOffset": 562,
    "fieldLength": 2
  },
  "GPS GPSDateStamp": {
    "printable": "2003:11:23",
    "tag": 29,
    "fieldType": 2,
    "values": "2003:11:23",
    "fieldOffset": 982,
    "fieldLength": 11
  },
  "GPS GPSLatitude": {
    "printable": "395456",
    "tag": 2,
    "fieldType": 5,
    "values": [
      39,
      54,
      56
    ],
    "fieldOffset": 910,
    "fieldLength": 24
  },
  "GPS GPSLatitudeRef": {
    "printable": "N",
    "tag": 1,
    "fieldType": 2,
    "values": "N",
    "fieldOffset": 842,
    "fieldLength": 2
  },
  "GPS GPSLongitude": {
    "printable": "1162327",
    "tag": 4,
    "fieldType": 5,
    "values": [
      116,
      23,
      27
    ],
    "fieldOffset": 934,
    "fieldLength": 24
  },
  "GPS GPSLongitudeRef": {
    "printable": "E",
    "tag": 3,
    "fieldType": 2,
    "values": "E",
    "fieldOffset": 866,
    "fieldLength": 2
  },
  "GPS GPSTimeStamp": {
    "printable": "18737",
    "tag": 7,
    "fieldType": 5,
    "values": [
      18,
      7,
      37
    ],
    "fieldOffset": 958,
    "fieldLength": 24
  },
  "GPS GPSVersionID": {
    "printable": "2200",
    "tag": 0,
    "fieldType": 1,
    "values": [
      2,
      2,
      0,
      0
    ],
    "fieldOffset": 830,
    "fieldLength": 4
  },
  "Image DateTime": {
    "printable": "2005:07:02 10:38:28",
    "tag": 306,
    "fieldType": 2,
    "values": "2005:07:02 10:38:28",
    "fieldOffset": 196,
    "fieldLength": 20
  },
  "Image ExifOffset": {
    "printable": "216",
    "tag": 34665,
    "fieldType": 4,
    "values": [
      216
    ],
    "fieldOffset": 114,
    "fieldLength": 4
  },
  "Image GPSInfo": {
    "printable": "820",
    "tag": 34853,
    "fieldType": 4,
    "values": [
      820
    ],
    "fieldOffset": 126,
    "fieldLength": 4
  },
  "Image Make": {
    "printable": "NIKON CORPORATION",
    "tag": 271,
    "fieldType": 2,
    "values": "NIKON CORPORATION",
    "fieldOffset": 134,
    "fieldLength": 18
  },
  "Image Model": {
    "printable": "NIKON D2H",
    "tag": 272,
    "fieldType": 2,
    "values": "NIKON D2H",
    "fieldOffset": 152,
    "fieldLength": 10
  },
  "Image Orientation": {
    "printable": "Horizontal (normal)",
    "tag": 274,
    "fieldType": 3,
    "values": [
      1
    ],
    "fieldOffset": 42,
    "fieldLength": 2
  },
  "Image ResolutionUnit": {
    "printable": "Pixels/Inch",
    "tag": 296,
    "fieldType": 3,
    "values": [
      2
    ],
    "fieldOffset": 78,
    "fieldLength": 2
  },
  "Image Software": {
    "printable": "Opanda PowerExif",
    "tag": 305,
    "fieldType": 2,
    "values": "Opanda PowerExif",
    "fieldOffset": 178,
    "fieldLength": 17
  },
  "Image XResolution": {
    "printable": "256",
    "tag": 282,
    "fieldType": 5,
    "values": [
      256
    ],
    "fieldOffset": 162,
    "fieldLength": 8
  },
  "Image YResolution": {
    "printable": "256",
    "tag": 283,
    "fieldType": 5,
    "values": [
      256
    ],
    "fieldOffset": 170,
    "fieldLength": 8
  },
  "JPEGThumbnail": {
    "type": "Buffer",
    "data": [
      255,
      216,
      255,
      219
    ]
  },
  "Thumbnail Compression": {
    "printable": "JPEG (old-style)",
    "tag": 259,
    "fieldType": 3,
    "values": [
      6
    ],
    "fieldOffset": 1004,
    "fieldLength": 2
  },
  "Thumbnail JPEGInterchangeFormat": {
    "printable": "1088",
    "tag": 513,
    "fieldType": 4,
    "values": [
      1088
    ],
    "fieldOffset": 1052,
    "fieldLength": 4
  },
  "Thumbnail JPEGInterchangeFormatLength": {
    "printable": "4034",
    "tag": 514,
    "fieldType": 4,
    "values": [
      4034
    ],
    "fieldOffset": 1064,
    "fieldLength": 4
  },
  "Thumbnail ResolutionUnit": {
    "printable": "Pixels/Inch",
    "tag": 296,
    "fieldType": 3,
    "values": [
      2
    ],
    "fieldOffset": 1040,
    "fieldLength": 2
  },
  "Thumbnail XResolution": {
    "printable": "72",
    "tag": 282,
    "fieldType": 5,
    "values": [
      72
    ],
    "fieldOffset": 1072,
    "fieldLength": 8
  },
  "Thumbnail YResolution": {
    "printable": "72",
    "tag": 283,
    "fieldType": 5,
    "values": [
      72
    ],
    "fieldOffset": 1080,
    "fieldLength": 8
  }
}