piexifjs

repository·master·Indexed 20 days ago

https://github.com/hmatoba/piexifjs

A lightweight JavaScript library for reading and modifying EXIF metadata in JPEG images. Compatible with client-side browsers (including IE11 and Opera 28), Node.js, and PhantomJS. It provides core functions to load EXIF data into JavaScript objects, dump objects into binary strings, insert metadata into JPEGs, and remove EXIF data entirely. Includes a GPSHelper for converting decimal degrees to DMS rational format.

Tokens
5K
Snippets
22
Records
23
Agent score
70%

What's inside piexifjs

  1. Handle multi-value Exif numeric types using Arrays

    master

    In piexifjs, if an Exif value type is numeric (BYTE, SHORT, LONG, RATIONAL, or SRATIONAL) and contains two or more values, it is expressed as a JavaScript Array.

    • For BYTE, SHORT, or LONG: Use a flat array of integers: [int, int, ...].
    • For RATIONAL or SRATIONAL: Use a nested array of integer pairs: [[int, int], [int, int], ...].

    Note: If the value type is numeric and the count is exactly one, a single-element array (e.g., [int]) is also accepted.

    | BYTE, SHORT, LONG   | [int, int, ...]               |
    | RATIONAL, SRATIONAL | [[int, int], [int, int], ...] |
  2. Read Exif values from a JPEG

    master

    To extract Exif metadata from a JPEG, use piexif.load(imageData). This returns an object containing the different IFD segments (like 0th, Exif, GPS, and thumbnail).

    You can iterate through these segments and use piexif.TAGS to map the numeric tag IDs to human-readable names.

    var exifObj = piexif.load(e.target.result);
    for (var ifd in exifObj) {
        if (ifd == "thumbnail") {
            continue;
        }
        console.log("-" + ifd);
        for (var tag in exifObj[ifd]) {
            console.log("  " + piexif.TAGS[ifd][tag]["name"] + ":" + exifObj[ifd][tag]);
        }
    }
  3. Insert Exif metadata into a JPEG

    master

    To insert new Exif metadata into a JPEG image, you must first construct an Exif object containing the desired IFD (Image File Directory) segments, dump it into bytes, and then insert those bytes into the image data.

    1. Create an object with keys 0th, Exif, and GPS.
    2. Use piexif.dump(exifObj) to convert the object into Exif bytes.
    3. Use piexif.insert(exifbytes, imageData) to merge the metadata into the original image string.

    Note: In a browser environment, the image data is typically handled as a Data URL via FileReader.

    var zeroth = {};
    var exif = {};
    var gps = {};
    zeroth[piexif.ImageIFD.Make] = "Make";
    exif[piexif.ExifIFD.DateTimeOriginal] = "2010:10:10 10:10:10";
    gps[piexif.GPSIFD.GPSVersionID] = [7, 7, 7, 7];
    
    var exifObj = {"0th":zeroth, "Exif":exif, "GPS":gps};
    var exifbytes = piexif.dump(exifObj);
    
    // In browser with FileReader:
    var inserted = piexif.insert(exifbytes, e.target.result);
  4. Example: Inserting custom EXIF data into a file upload

    master

    This example demonstrates how to use the File API to read a user-uploaded image, create a custom EXIF object using IFD constants, and insert that data back into the image as a DataURL.

    <input type="file" id="files" />
    <script src="/js/piexif.js"></script>
    <script>
    function handleFileSelect(evt) {
        var file = evt.target.files[0];
        
        var zeroth = {};
        var exif = {};
        var gps = {};
        
        // Using IFD constants to set metadata
        zeroth[piexif.ImageIFD.Make] = "Make";
        zeroth[piexif.ImageIFD.XResolution] = [777, 1];
        zeroth[piexif.ImageIFD.YResolution] = [777, 1];
        zeroth[piexif.ImageIFD.Software] = "Piexifjs";
        
        exif[piexif.ExifIFD.DateTimeOriginal] = "2010:10:10 10:10:10";
        exif[piexif.ExifIFD.LensMake] = "LensMake";
        exif[piexif.ExifIFD.Sharpness] = 777;
        exif[piexif.ExifIFD.LensSpecification] = [[1, 1], [1, 1], [1, 1], [1, 1]];
        
        gps[piexif.GPSIFD.GPSVersionID] = [7, 7, 7, 7];
        gps[piexifif.GPSIFD.GPSDateStamp] = "1999:99:99 99:99:99";
        
        // Construct the full EXIF object
        var exifObj = {"0th":zeroth, "Exif":exif, "GPS":gps};
        var exifStr = piexif.dump(exifObj);
    
        var reader = new FileReader();
        reader.onload = function(e) {
            // Insert the new EXIF string into the DataURL
            var inserted = piexif.insert(exifStr, e.target.result);
    
            var image = new Image();
            image.src = inserted;
            image.width = 200;
            var el = $("<div></div>").append(image);
            $("#resized").prepend(el);
        };
        reader.readAsDataURL(file);
    }
    
    document.getElementById('files').addEventListener('change', handleFileSelect, false);
    </script>
  5. Handle GPS coordinates with GPSHelper

    master

    When setting GPS metadata, use piexif.GPSHelper.degToDmsRational(coordinate) to convert decimal degrees into the rational format required by the Exif standard. You must also set the appropriate Reference tags (e.g., GPSLatitudeRef or GPSLongitudeRef) to indicate North/South or East/West.

    var lat = 59.43553989213321;
    var lng = 24.73842144012451;
    var gpsIfd = {};
    
    gpsIfd[piexif.GPSIFD.GPSLatitudeRef] = lat < 0 ? 'S' : 'N';
    gpsIfd[piexif.GPSIFD.GPSLatitude] = piexif.GPSHelper.degToDmsRational(lat);
    gpsIfd[piexif.GPSIFD.GPSLongitudeRef] = lng < 0 ? 'W' : 'E';
    gpsIfd[piexif.GPSIFD.GPSLongitude] = piexif.GPSHelper.degToDmsRational(lng);
  6. Use piexifjs in Node.js

    master

    In a Node.js environment, you can use require("piexifjs"). Since Node.js handles files as Buffers, you should convert the file buffer to a binary string using .toString("binary") before processing with piexif.insert(), and then convert the resulting string back to a Buffer using Buffer.from(newData, "binary") when saving.

    var piexif = require("piexifjs");
    var fs = require("fs");
    
    var jpeg = fs.readFileSync("in.jpg");
    var data = jpeg.toString("binary");
    
    var exifObj = {"0th":{}, "Exif":{}, "GPS":{}};
    // ... populate exifObj ...
    
    var exifbytes = piexif.dump(exifObj);
    var newData = piexif.insert(exifbytes, data);
    var newJpeg = Buffer.from(newData, "binary");
    fs.writeFileSync("out.jpg", newJpeg);
  7. Use the Piexifjs core functions for Exif manipulation

    master

    Piexifjs provides four primary functions to handle Exif data within JPEG images. You can use these to read Exif data as a JavaScript object, convert objects back to binary strings, insert Exif data into a JPEG, or remove Exif data entirely.

    /* Core API functions */
    
    // 1. Get exif data as an object from JPEG binary data
    const exifObj = piexif.load(jpegData);
    
    // 2. Get exif binary as a string to insert into a JPEG
    const exifBytes = piexif.dump(exifObj);
    
    // 3. Insert exif into JPEG
    const newJpegData = piexif.insert(exifBytes, jpegData);
    
    // 4. Remove exif from JPEG
    const jpegWithoutExif = piexif.remove(jpegData);
  8. Read and modify EXIF data with piexifjs

    master

    Piexifjs provides a set of core functions to load, manipulate, and re-insert EXIF data into JPEG images.

    Core API Methods

    • piexif.load(jpegData): Extracts EXIF data from a JPEG and returns it as an object.
      • jpegData must be a string starting with a DataURL (data:image/jpeg;base64,...), the binary header \xff\xd8, or the string Exif.
    • piexif.dump(exifObj): Converts an EXIF object back into a string format suitable for insertion into a JPEG.
    • piexif.insert(exifStr, jpegData): Inserts an EXIF string into a JPEG.
      • If jpegData is a DataURL, it returns the new JPEG as a DataURL.
      • If jpegData is a binary string, it returns the new JPEG as a binary string.
    • piexif.remove(jpegData): Removes all EXIF data from a JPEG.
      • If jpegData is a DataURL, it returns the new JPEG as a DataURL.
      • If jpegData is a binary string, it returns the new JPEG as a binary string.
    // Load EXIF
    var exifObj = piexif.load(jpegData);
    
    // Convert object back to string
    var exifStr = piexif.dump(exifObj);
    
    // Insert into JPEG
    var newJpeg = piexif.insert(exifStr, jpegData);
    
    // Remove EXIF
    var cleanJpeg = piexif.remove(jpegData);