Search code examples
javascriptnode.jsexifpiexif

How to read image into base64 without losing EXIF data?


I'm trying to read one local image created with a different exif.Orientation based on the degrees that it was rotated.

const exifData = piexif.load(data.toString("binary"));

    // Set the desired orientation value in the EXIF data
    exifData["0th"][piexif.ImageIFD.Orientation] = exifOrientation;

    // Encode the modified EXIF data
    const modifiedExifBytes = piexif.dump(exifData);

    // Update the image buffer with the modified EXIF data
    const modifiedImageBuffer = piexif.insert(
      modifiedExifBytes,
      data.toString("binary")
    );

    // Write the modified image buffer to the output file
    const newPath = path.replace("binary.", "binary-rotated.");
    fs.writeFileSync(newPath, modifiedImageBuffer, {
      encoding: "binary",
    });
    const imageFile = fs.readFileSync(newPath);
    const base64Data = Buffer.from(imageFile).toString("base64");

But, my base64Data is constantly losing the EXIF metadata. Can I read it in a different way? I need the base64 encoded with the exif orientation to make an API call.


Solution

  • The intention for this was processing OCR with google vision so was able to workaround this issue by:

    • Where data is my buffer.
    1. Retrieving EXIF metadata Orientation from the image with piexif
      // Reads EXIF data from the file
      const exifData = piexif.load(data.toString("binary"));
      
      // Get the angle to rotate the image by its EXIF orientation
      // If the image does not have EXIF orientation, will be rotate to 0
      let angleToBeRotated = getImageAngle(
       exifData["0th"][piexif.ImageIFD.Orientation]
      );
      
    2. Bake/Burn in image EXIF orientation with piexif
      const bakedImageBinary = piexif.remove(data.toString("binary"));
      
      // Write the modified image buffer to the output file
      const newPath = path.replace("binary.", "binary-rotated.");
      fs.writeFileSync(newPath, bakedImageBinary, {
       encoding: "binary",
      });
      );
      
    3. Rotate the image with Jimp to the EXIF orientation
      const image = await Jimp.read(newPath);
      
      image.rotate(angleToBeRotated);
      
      image.quality(90);
      
      const base64 = await image.getBase64Async(Jimp.AUTO);
      
      

    In that way, I can ensure the base64 created is rotated with the correct orientation. Hope this can give a north for anywho in the future. If I manage to find a better way to do that, will update this.