JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images

前端 未结 12 907
花落未央
花落未央 2020-11-22 11:59

Digital camera photos are often saved as JPEG with an EXIF \"orientation\" tag. To display correctly, images need to be rotated/mirrored depending on which orientation is se

12条回答
  •  死守一世寂寞
    2020-11-22 12:35

    For those who have a file from an input control, don't know what its orientation is, are a bit lazy and don't want to include a large library below is the code provided by @WunderBart melded with the answer he links to (https://stackoverflow.com/a/32490603) that finds the orientation.

    function getDataUrl(file, callback2) {
            var callback = function (srcOrientation) {
                var reader2 = new FileReader();
                reader2.onload = function (e) {
                    var srcBase64 = e.target.result;
                    var img = new Image();
    
                    img.onload = function () {
                        var width = img.width,
                            height = img.height,
                            canvas = document.createElement('canvas'),
                            ctx = canvas.getContext("2d");
    
                        // set proper canvas dimensions before transform & export
                        if (4 < srcOrientation && srcOrientation < 9) {
                            canvas.width = height;
                            canvas.height = width;
                        } else {
                            canvas.width = width;
                            canvas.height = height;
                        }
    
                        // transform context before drawing image
                        switch (srcOrientation) {
                            case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
                            case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
                            case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
                            case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
                            case 6: ctx.transform(0, 1, -1, 0, height, 0); break;
                            case 7: ctx.transform(0, -1, -1, 0, height, width); break;
                            case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
                            default: break;
                        }
    
                        // draw image
                        ctx.drawImage(img, 0, 0);
    
                        // export base64
                        callback2(canvas.toDataURL());
                    };
    
                    img.src = srcBase64;
                }
    
                reader2.readAsDataURL(file);
            }
    
            var reader = new FileReader();
            reader.onload = function (e) {
    
                var view = new DataView(e.target.result);
                if (view.getUint16(0, false) != 0xFFD8) return callback(-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 callback(-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 callback(view.getUint16(offset + (i * 12) + 8, little));
                    }
                    else if ((marker & 0xFF00) != 0xFF00) break;
                    else offset += view.getUint16(offset, false);
                }
                return callback(-1);
            };
            reader.readAsArrayBuffer(file);
        }
    

    which can easily be called like such

    getDataUrl(input.files[0], function (imgBase64) {
          vm.user.BioPhoto = imgBase64;
    });
    

提交回复
热议问题