# cyexifparser

> An image EXIF parser that conforms to EXIF V2.3 specifications

Latest version **1.0.0** (published 2019-10-09) · ISC license · 0 weekly downloads

## Install

```sh
npm install cyexifparser
pnpm add cyexifparser
yarn add cyexifparser
bun add cyexifparser
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2019-10-09 |
| First published | 2017-12-16 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 5.7 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Cyril Adelekan |
| Maintainers | cyrilinc |
| Keywords | EXIF, Image, GPS, metadata, tag, Flashpix, JPEG, TIFF, Parser |

## Links

- npm: https://www.npmjs.com/package/cyexifparser
- npm.io page: https://npm.io/package/cyexifparser

## Alternatives

- [babylon](https://npm.io/package/babylon.md) — 5.1M weekly downloads
- [csscolorparser](https://npm.io/package/csscolorparser.md) — 3.7M weekly downloads
- [expr-eval-fork](https://npm.io/package/expr-eval-fork.md) — 1.5M weekly downloads
- [@leeoniya/ufuzzy](https://npm.io/package/@leeoniya/ufuzzy.md) — 247.7K weekly downloads
- [xml-parser](https://npm.io/package/xml-parser.md) — 78.4K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2019-10-09
- 0.0.4-beta — 2017-12-17
- 0.0.3-beta — 2017-12-16
- 0.0.2-beta — 2017-12-16
- 0.0.1-beta — 2017-12-16

## README

# 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](https://www.npmjs.com/package/cyexifparser):
```python
$ npm install --save cyexifparser
```

## Options

| Option  | Type  | Description  |
|---|---|---|
|  debug |  Boolean | Display Debug information when parsing an image  |
| fullData  |  Boolean | Get 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 |
| selectedKeys | Array  | The array of string containing keys to extrtact from the Exif data `alternate to fullData`  also `printable` and  `values` sub-attributes only |
|  contains | String  |  The 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 ####
```javascript
	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 ####

```javascript
	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 :
```javascript
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:
```python
$ npm install && npm test
```

## Author ##
Cyril Adelekan [twitter](https://twitter.com/CyrilInc)


## Sample output on a successful extraction of EXIF data ##
```javascript
{
  "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
  }
}
```

---
_Source: https://npm.io/package/cyexifparser · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
