exif.js 微信小程序适配,获取上传图片原始信息

3,468 阅读2分钟

exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。但是,exif.js 在小程序内使用会有问题,下面就来解决这些问题。

版本

  • exif-js 2.3.0
  • 小程序调试基础库 2.14.4
  • 开发者工具 1.05.2102010

安装 exif.js

npm install exif-js

安装之后使用小程序开发者工具构建 npm。

获取图片文件

使用 wx.chooseImage 获取临时文件路径

wx.chooseImage({
	count: 1,
    sizeType: ['original'],
    sourceType: ['album', 'camera'],
    success: (res) => {
        // 临时文件路径  http://tmp/UcfVFoFlBHisb890f9c1e0c2edd33eb4c18b3f15a427.jpg
        const filePath = res.tempFilePaths[0]; 
    }
})

使用 wx.getFileSystemManager().readFile 将临时文件路径转换为 ArrayBuffer

wx.getFileSystemManager().readFile({
    filePath,
     success: (res) => {
        // 这里的 fileBuffer 是 ArrayBuffer 格式 
     	const fileBuffer = res.data;
    }
})

解决报错

这里提示 Image of undefined , 因为小程序中没有 dom 对象,所以调用 self.Image 会报错

解决方法:在函数内添加

var self = window || this;

虽然没有报错了,但是也没有获取到数据,因为,函数 getImageData 没有调用 handleBinaryFile 函数。

解决方法:修改 getImageData 函数

function getImageData(img, callback) {
    function handleBinaryFile(binFile) {
        var data = findEXIFinJPEG(binFile);
        img.exifdata = data || {};
        var iptcdata = findIPTCinJPEG(binFile);
        img.iptcdata = iptcdata || {};
        if (EXIF.isXmpEnabled) {
            var xmpdata = findXMPinJPEG(binFile);
            img.xmpdata = xmpdata || {};
        }
        if (callback) {
            callback.call(img);
        }
    }

    if (img.src) {
        if (/^data\:/i.test(img.src)) { // Data URI
            var arrayBuffer = base64ToArrayBuffer(img.src);
            handleBinaryFile(arrayBuffer);

        } else if (/^blob\:/i.test(img.src)) { // Object URL
            var fileReader = new FileReader();
            fileReader.onload = function (e) {
                handleBinaryFile(e.target.result);
            };
            objectURLToBlob(img.src, function (blob) {
                fileReader.readAsArrayBuffer(blob);
            });
        } else {
            var http = new XMLHttpRequest();
            http.onload = function () {
                if (this.status == 200 || this.status === 0) {
                    handleBinaryFile(http.response);
                } else {
                    throw "Could not load image";
                }
                http = null;
            };
            http.open("GET", img.src, true);
            http.responseType = "arraybuffer";
            http.send(null);
        }
    } else if (self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
        var fileReader = new FileReader();
        fileReader.onload = function (e) {
            if (debug) console.log("Got file of length " + e.target.result.byteLength);
            handleBinaryFile(e.target.result);
        };

        fileReader.readAsArrayBuffer(img);
    }
    // 添加一个判断
    else if (img instanceof ArrayBuffer) {
        handleBinaryFile(img);
    }
}

ps:这里有个坑就是,微信开发者工具 img instanceof ArrayBuffer 结果是 false ,真机调试的时候是 true

这里提示的 n is not defined 找到 n 在 函数 getStringFromDB 中未声明就使用了,只需将 n 改完局部变量即可。

解决方法:修改 n 为局部变量

function getStringFromDB(buffer, start, length) {
    var outstr = "";
    // 修改 n 为局部变量
    for (let n = start; n < start+length; n++) {
        outstr += String.fromCharCode(buffer.getUint8(n));
    }
    return outstr;
}

Blob is not defined,小程序暂不支持 Blob 对象。

解决方法:在文件的开头添加

var Blob = Blob || function () { };

终于没有报错了。

这样就可以获取到图片信息了。

调用方法

import EXIF from 'exif-js';

function gainImageInfo(params) {
    wx.getFileSystemManager().readFile({
        filePath,
        success: res => {
            const fileBuffer = res.data;
            EXIF.getData(fileBuffer, function () {
                // 这里的 exifTags 就是图片的原始信息
                let exifTags = EXIF.getAllTags(fileBuffer);
            })
        }
    })
}