HTML5 移动端“拍照”图片上传后角度问题

现象

在移动端页面中采用 file 调用原生的图片上传功能时候,发现上传后的图片角度会有奇怪的现象。如竖屏拍照的图片,上传后是倒立的。如果是需要做旋转预览的话,这个时候需要额外做一些工作。

原因

不多说,自己上网查。

解决方案。

来自于:https://github.com/Tencent/weui.js?files=1

辅助函数:

function dataURItoBuffer(dataURI){
        var byteString = atob(dataURI.split(',')[1]);
        var buffer = new ArrayBuffer(byteString.length);
        var view = new Uint8Array(buffer);
        for (var i = 0; i < byteString.length; i++) {
            view[i] = byteString.charCodeAt(i);
        }
        return buffer;
    }
    function dataURItoBlob(dataURI) {
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
        var buffer = dataURItoBuffer(dataURI);
        return new Blob([buffer], {type: mimeString});
    }

    /**
     * 获取图片的orientation
     * ref to http://stackoverflow.com/questions/7584794/accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side
     */
    function getOrientation(buffer){
        var view = new DataView(buffer);
        if (view.getUint16(0, false) != 0xFFD8) return -2;
        var length = view.byteLength, offset = 2;
        while (offset < length) {
            var marker = view.getUint16(offset, false);
            offset += 2;
            if (marker == 0xFFE1) {
                if (view.getUint32(offset += 2, false) != 0x45786966) return -1;
                var little = view.getUint16(offset += 6, false) == 0x4949;
                offset += view.getUint32(offset + 4, little);
                var tags = view.getUint16(offset, little);
                offset += 2;
                for (var i = 0; i < tags; i++)
                    if (view.getUint16(offset + (i * 12), little) == 0x0112)
                        return view.getUint16(offset + (i * 12) + 8, little);
            }
            else if ((marker & 0xFF00) != 0xFF00) break;
            else offset += view.getUint16(offset, false);
        }
        return -1;
    }

    /**
     * 修正拍照时图片的方向
     * ref to http://stackoverflow.com/questions/19463126/how-to-draw-photo-with-correct-orientation-in-canvas-after-capture-photo-by-usin
     */
    function orientationHelper(canvas, ctx, orientation) {
        const w = canvas.width, h = canvas.height;
        if(orientation > 4){
            canvas.width = h;
            canvas.height = w;
        }
        switch (orientation) {
            case 2:
                ctx.translate(w, 0);
                ctx.scale(-1, 1);
                break;
            case 3:
                ctx.translate(w, h);
                ctx.rotate(Math.PI);
                break;
            case 4:
                ctx.translate(0, h);
                ctx.scale(1, -1);
                break;
            case 5:
                ctx.rotate(0.5 * Math.PI);
                ctx.scale(1, -1);
                break;
            case 6:
                ctx.rotate(0.5 * Math.PI);
                ctx.translate(0, -h);
                break;
            case 7:
                ctx.rotate(0.5 * Math.PI);
                ctx.translate(w, -h);
                ctx.scale(-1, 1);
                break;
            case 8:
                ctx.rotate(-0.5 * Math.PI);
                ctx.translate(-w, 0);
                break;
        }
    }

在操作 img2DataURL 类似的过程中,调用如下:

// 图片方向角
var orientation = null;
var src = null;
var fid = file.id;
var reader = new FileReader();
reader.readAsDataURL(file.attributes.h5File);
reader.onload = function (e) {
    var image = new Image();
    image.src = e.target.result;
    orientation = getOrientation(dataURItoBuffer(e.target.result));
    console.log('orientation',orientation)
    image.onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width = this.naturalWidth;
        canvas.height = this.naturalHeight;
        var ctx = canvas.getContext("2d");
        if(orientation > 0){
            orientationHelper(canvas, ctx, orientation);
        }

        ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight);
        src = canvas.toDataURL(file.attributes.h5File.type, .8);
        var tmpl = '<li class="weui-uploader__file weui-uploader__file_status" data-fid="' +  fid + '"style="background-image:url(#url#)"><div class="weui-uploader__file-content"></div></li>';
        $uploaderFiles.append($(tmpl.replace('#url#', src)));
    };
};

即可修正在预览中的图片角度问题。

© DeveWork.com 2018. sitemap  统计 Updated at 2018-01-26 00:16

results matching ""

    No results matching ""