移动端个别安装手机图片上传旋转90度 exif.js控制

做微信wap页项目的时候,遇到小米6拍照上传图片旋转的问题,后来查找资料得到

Orientation,进行判断并运用canvas把图片旋转后再上传解决了问题

exif.js读取图像的元数据https://www.cnblogs.com/niuboren/archive/2016/09/19/5883796.html

<script>
EXIF.getData(file, function() {  
            Orientation = EXIF.getTag(this, 'Orientation');          
});
var img_url = URL.createObjectURL(file);
imgwh = new Image();    
imgwh.src = img_url;
imgwh.onload = function () {
    var imgWidth = this.width,
    imgHeight = this.height;            
    var canvas = document.createElement("canvas"),
    ctx = canvas.getContext('2d');
    canvas.width = imgWidth;
    canvas.height = imgHeight;	
	if(Orientation && Orientation != 1){    //小米6竖着拍摄旋转问题
	    switch(Orientation){
	        case 6:     // 旋转90度
	            canvas.width = imgHeight;    
	            canvas.height = imgWidth;    
	            ctx.rotate(Math.PI / 2);
	            ctx.fillStyle = "#fff";
	            ctx.fillRect(0, 0, imgWidth, imgHeight);
	            ctx.drawImage(this, 0, -imgHeight);
	            break;
	        case 3:     // 旋转180度
	            ctx.rotate(Math.PI); 
	            ctx.fillStyle = "#fff";
	            ctx.fillRect(0, 0, imgWidth, imgHeight);
	            ctx.drawImage(this, -imgWidth, -imgHeight);
	            break;
	        case 8:     // 旋转-90度
	            canvas.width = imgHeight;    
	            canvas.height = imgWidth;    
	            ctx.rotate(3 * Math.PI / 2); 
	            ctx.fillStyle = "#fff";
	            ctx.fillRect(0, 0, imgWidth, imgHeight);
	            ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
	            break;
	    }
	}	

}
</script> 

exif.js

var EXIF = {};
var TiffTags = EXIF.TiffTags = {
    0x0112: "Orientation"
};

function imageHasData(img) {
    return !!(img.exifdata);
}

function getImageData(img, callback) {
    function handleBinaryFile(binFile) {
        var data = findEXIFinJPEG(binFile);
        img.exifdata = data || {};
        if (callback) {
            callback.call(img);
        }
    }

    if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) {
        var fileReader = new FileReader();
        fileReader.onload = function (e) {
            handleBinaryFile(e.target.result);
        };
        fileReader.readAsArrayBuffer(img);
    }
}

function findEXIFinJPEG(file) {
    var dataView = new DataView(file);

    if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
        return false; // not a valid jpeg
    }

    var offset = 2,
        length = file.byteLength,
        marker;

    while (offset < length) {
        if (dataView.getUint8(offset) != 0xFF) {
            return false; // not a valid marker, something is wrong
        }

        marker = dataView.getUint8(offset + 1);

        if (marker == 225) {
            return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
        } else {
            offset += 2 + dataView.getUint16(offset + 2);
        }
    }
}

function readTags(file, tiffStart, dirStart, strings, bigEnd) {
    var entries = file.getUint16(dirStart, !bigEnd),
        tags = {},
        entryOffset, tag,
        i;

    for (i = 0; i < entries; i++) {
        entryOffset = dirStart + i * 12 + 2;
        tag = strings[file.getUint16(entryOffset, !bigEnd)];
        tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
    }
    return tags;
}

function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) {
    var type = file.getUint16(entryOffset + 2, !bigEnd),
        numValues = file.getUint32(entryOffset + 4, !bigEnd),
        valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart,
        offset,
        vals, val, n,
        numerator, denominator;
    switch (type) {
        case 1: // byte, 8-bit unsigned int
        case 7: // undefined, 8-bit byte, value depending on field
            if (numValues == 1) {
                return file.getUint8(entryOffset + 8, !bigEnd);
            } else {
                offset = numValues > 4 ? valueOffset : (entryOffset + 8);
                vals = [];
                for (n = 0; n < numValues; n++) {
                    vals[n] = file.getUint8(offset + n);
                }
                return vals;
            }

        case 2: // ascii, 8-bit byte
            offset = numValues > 4 ? valueOffset : (entryOffset + 8);
            return getStringFromDB(file, offset, numValues - 1);

        case 3: // short, 16 bit int
            if (numValues == 1) {
                return file.getUint16(entryOffset + 8, !bigEnd);
            } else {
                offset = numValues > 2 ? valueOffset : (entryOffset + 8);
                vals = [];
                for (n = 0; n < numValues; n++) {
                    vals[n] = file.getUint16(offset + 2 * n, !bigEnd);
                }
                return vals;
            }

        case 4: // long, 32 bit int
            if (numValues == 1) {
                return file.getUint32(entryOffset + 8, !bigEnd);
            } else {
                vals = [];
                for (n = 0; n < numValues; n++) {
                    vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd);
                }
                return vals;
            }

        case 5: // rational = two long values, first is numerator, second is denominator
            if (numValues == 1) {
                numerator = file.getUint32(valueOffset, !bigEnd);
                denominator = file.getUint32(valueOffset + 4, !bigEnd);
                val = new Number(numerator / denominator);
                val.numerator = numerator;
                val.denominator = denominator;
                return val;
            } else {
                vals = [];
                for (n = 0; n < numValues; n++) {
                    numerator = file.getUint32(valueOffset + 8 * n, !bigEnd);
                    denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd);
                    vals[n] = new Number(numerator / denominator);
                    vals[n].numerator = numerator;
                    vals[n].denominator = denominator;
                }
                return vals;
            }

        case 9: // slong, 32 bit signed int
            if (numValues == 1) {
                return file.getInt32(entryOffset + 8, !bigEnd);
            } else {
                vals = [];
                for (n = 0; n < numValues; n++) {
                    vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd);
                }
                return vals;
            }

        case 10: // signed rational, two slongs, first is numerator, second is denominator
            if (numValues == 1) {
                return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd);
            } else {
                vals = [];
                for (n = 0; n < numValues; n++) {
                    vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 * n, !bigEnd);
                }
                return vals;
            }
    }
}

function getStringFromDB(buffer, start, length) {
    var outstr = "";
    for (n = start; n < start + length; n++) {
        outstr += String.fromCharCode(buffer.getUint8(n));
    }
    return outstr;
}

function readEXIFData(file, start) {
    if (getStringFromDB(file, start, 4) != "Exif") {
        return false;
    }

    var bigEnd,
        tags, tag,
        exifData, gpsData,
        tiffOffset = start + 6;

    // test for TIFF validity and endianness
    if (file.getUint16(tiffOffset) == 0x4949) {
        bigEnd = false;
    } else if (file.getUint16(tiffOffset) == 0x4D4D) {
        bigEnd = true;
    } else {
        return false;
    }

    if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) {
        return false;
    }

    var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);
    if (firstIFDOffset < 0x00000008) {
        return false;
    }

    tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);

    return tags;
}

EXIF.getData = function (img, callback) {
    if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false;

    if (!imageHasData(img)) {
        getImageData(img, callback);
    } else {
        if (callback) {
            callback.call(img);
        }
    }
    return true;
}

EXIF.getTag = function (img, tag) {
    if (!imageHasData(img)) return;
    return img.exifdata[tag];
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移动Vue Vant的Uploader组件可以很方便地实现上、压缩和旋转图片功能。首先,我们需要在Vue项目中引入Vue Vant库,并在需要使用Uploader的组件中注册该组件。 在页面中使用Uploader组件时,我们可以设置相关的属性来实现功能需求。首先是上图片功能,可以通过设置`action`属性来指定图片的后接口地址。上成功后,可以通过监听`@success`事件来处理上成功的逻辑,例如显示上成功的提示信息或者将上成功的图片URL保存到数据库等。 对于压缩图片的功能,我们可以使用该组件提供的`beforeRead`方法来获取用户要上图片文件对象。然后,利用`HTMLCanvasElement`的`toBlob`方法对图片进行压缩,并将压缩后的图片对象给Uploader组件进行上。在压缩图片时,可以设置压缩的尺寸或者压缩的质量、压缩比等参数,以控制压缩后的图片大小适应实际需求。 要实现图片旋转的功能,我们可以利用`EXIF.js`库来读取图片EXIF信息,获取图片的拍摄方向。然后,根据拍摄方向来确定图片需要旋转的角度,再借助`canvas`的`rotate`方法对图片进行旋转旋转后的图片可以在`@success`事件触发后重新渲染到页面上,或者直接发送到后进行保存。 总结来说,移动Vue Vant的Uploader组件通过设置相关属性和监听事件,配合压缩工具和EXIF库,可以非常方便地实现图片、压缩和旋转功能,满足移动图片处理的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值