exif-js / exif-js

JavaScript library for reading EXIF image metadata

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a convinient way to add exif to canvas for uploading?

womengnan opened this issue · comments

from this link https://www.jianshu.com/p/8a4b974aee64 , we can extract and insert exif info to canvas before uploading it to the server.

Is there a similar method to do so in exif-js?

Thanks

` //@ canvas 压缩图片保存原图片exif核心代码

// 工具函数 将 base64 转 ArrayBuffer
base64ToArrayBuffer(base64, contentType) {
  contentType =
    contentType || base64.match(/^data\:([^\;]+)\;base64,/im)[1] || ""; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
  base64 = base64.replace(/^data\:([^\;]+)\;base64,/gim, "");
  // btoa是binary to ascii,将binary的数据用ascii码表示,即Base64的编码过程
  // atob则是ascii to binary,用于将ascii码解析成binary数据
  var binary = atob(base64);
  var len = binary.length;
  var buffer = new ArrayBuffer(len);
  var view = new Uint8Array(buffer);
  for (var i = 0; i < len; i++) {
    view[i] = binary.charCodeAt(i);
  }
  return buffer;
},
transformArrayBufferToBase64(buffer) {
  var binary = "";
  var bytes = new Uint8Array(buffer);
  for (var len = bytes.byteLength, i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return `data:image/jpeg;base64,${window.btoa(binary)}`;
},

// 获取 0xFFE0~0xFFEF 开头的应用标记片段
getSegments(arrayBuffer) {
  var head = 0,
    segments = [];
  var length, endPoint, seg;
  var arr = [].slice.call(new Uint8Array(arrayBuffer), 0);

  while (true) {
    // SOS(Start of Scan, 由 0xff 0xda 开头)
    // 遍历到 SOS 表示已经遍历完所有标记,再往下就是图像数据流了,直接 break
    if (arr[head] === 0xff && arr[head + 1] === 0xda) {
      break;
    }

    // SOI(Start of Image)是 JPG 文件的开头内容,由 0xff 0xd8 开头
    if (arr[head] === 0xff && arr[head + 1] === 0xd8) {
      head += 2;
    }
    // 找出每个标记片段
    else {
      // 每个标记开头后跟着的两个字节记录了该标记所记录内容的长度
      length = arr[head + 2] * 256 + arr[head + 3]; // 内容长度
      endPoint = head + length + 2; // 内容结束位置
      // 从0xff开头,到标记数据内容结束全部截出来
      seg = arr.slice(head, endPoint);
      head = endPoint;
      // push整个标记信息
      segments.push(seg);
    }
    if (head > arr.length) {
      break;
    }
  }
  return segments;
},
// 从标记片段筛选 & 取出 exif 信息
getEXIF(segments) {
  if (!segments.length) {
    return [];
  }
  var seg = [];
  for (var x = 0; x < segments.length; x++) {
    var s = segments[x];
    // 0xff 0xe1开头的才是 exif数据(即app1)
    if (s[0] === 0xff && s[1] === 0xe1) {
      // app1 exif 0xff 0xe1
      seg = seg.concat(s);
    }
  }
  return seg;
},
// 拼接 Exif 到压缩后的 base64 中:
// 插入 Exif 信息
insertEXIF(resizedImg, exifArr) {
  var arr = [].slice.call(new Uint8Array(resizedImg), 0);
  //不是标准的JPEG文件
  if (arr[2] !== 0xff || arr[3] !== 0xe0) {
    return resizedImg;
  }
  var app0_length = arr[4] * 256 + arr[5]; //两个字节

  // 拼接文件 SOI + EXIF + 去除APP0的图像信息
  var newImg = [0xff, 0xd8].concat(exifArr, arr.slice(4 + app0_length));
  return new Uint8Array(newImg);
},

`