前端压缩图片并获取exif信息

转载自http://icaife.github.io/2015/05/19/js-compress-JPEG-width-exif/

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <style>
    </style>

</head>

<body>

    <div>
        <input type="file" id="filedom" />
        <img src="#" width="200" id="img">
        <br>
        <button id="btn">获取</button>
    </div>
    <script>
        var ImageTool = { /* * @param rawImageArray{ArrayBuffer|Array|Blob} */
            getSegments: function (rawImage, callback) {
                if (rawImage instanceof Blob) {
                    var that = this;
                    var fileReader = new FileReader();
                    fileReader.onload = function () {
                        that.getSegments(fileReader.result,
                            callback);
                    };
                    fileReader.readAsArrayBuffer(rawImage);
                } else {
                    if (!rawImage.length && !rawImage.byteLength) {
                        return [];
                    }
                    var head = 0,
                        segments = [];
                    var length, endPoint, seg;
                    var arr = [].slice.call(new Uint8Array(rawImage), 0);
                    while (1) {
                        if (arr[head] === 0xff && arr[head + 1] === 0xda) { //Start of Scan 0xff 0xda SOS 
                            break;
                        }
                        if (arr[head] === 0xff && arr[head +
                                1] === 0xd8) { //Start of Image 0xff 0xd8 SOI 
                            head += 2;
                        } else { //找到每个marker 
                            length = arr[head + 2] * 256 + arr[head + 3]; //每个marker 后 的两个字节为 该marker信息的长度 
                            endPoint = head + length + 2;
                            seg = arr.slice(head, endPoint); //截取信息 
                            head = endPoint;
                            segments.push(seg); //将每个marker + 信息 push 进去。 
                        }
                        if (head > arr.length) {
                            break;
                        }
                    }
                    callback(segments);
                }
            },
            /* 
            * @param
            resizedImg {
                ArrayBuffer | Blob
            }* @param exifArr {
                Array | Uint8Array
            }*/
            insertEXIF: function (resizedImg, exifArr, callback) {
                if (resizedImg instanceof Blob) {
                    var that = this;
                    var fileReader = new FileReader();
                    fileReader.onload = function () {
                        that.insertEXIF(fileReader.result,
                            exifArr, callback);
                    };
                    fileReader.readAsArrayBuffer(resizedImg);
                } else {
                    var arr = [].slice.call(new Uint8Array(resizedImg),
                        0);
                    if (arr[2] !== 0xff || arr[3] !== 0xe0) { // throw new Error("Couldn't find APP0 marker from resized image data.");
                        return resizedImg; //不是标准的JPEG文件 
                    }
                    var app0_length = arr[4] * 256 + arr[5]; //两个字节 
                    var newImage = [0xff, 0xd8].concat(exifArr, arr.slice(4 +
                        app0_length)); //合并文件 SOI + EXIF + 去除APP0的图像信息 
                    callback(new Uint8Array(newImage));
                }
            },

            getEXIF: function (segments) {
                if (!segments.length) {
                    return [];
                }
                var seg = [];
                for (var x = 0; x < segments.length; x++) {
                    var s = segments[x]; //TODO segments 
                    if (s[0] === 0xff && s[1] === 0xe1) { // app1 exif 0xff 0xe1 seg=s eg.concat(s);
                    }
                }
                return seg;
            },
            decode64: function (base64) {
                var b64 = "data:image/jpeg;base64,";
                if (base64.slice(0,
                        23) !== b64) {
                    return [];
                }
                var binStr = window.atob(base64.replace(b64, ""));
                var buf = new Uint8Array(binStr.length);
                for (var i = 0, len = binStr.length; i < len; i++) {
                    buf[i] = binStr.charCodeAt(i);
                }
                return buf;
            },
            /* *@param arr{Array} */
            encode64: function (arr) {
                var data = "";
                for (var i = 0, len = arr.length; i < len; i++) {
                    data += String.fromCharCode(arr[i]);
                }
                return "data:image/jpeg;base64," + window.btoa(data);
            }
        };
        var filedom = document.getElementById("file");
        var imgdom = document.getElementById("img");
        var btn = document.getElementById("btn");
        btn.onclick = function () {
            var imgFile = filedom.files[0];
            if (!imgFile) {
                alert("请选择图片文件!");
                return false;
            }
            showImage(imgFile, function (src) {
                imgdom.src = src;
                imgdom.onload = function () {
                    imageResize(imgdom, 400, 225, 1, function (blob) {
                        ImageTool.getSegments(imgFile, function (segments) {
                            var exif = ImageTool.getEXIF(segments); //获取exif信息 
                            ImageTool.insertEXIF(blob, exif, function (newImage) {
                                showImage(new Blob([newImage], {
                                        type: "image/jpeg"
                                    }),
                                    function (src) {
                                        var img = new Image();
                                        img.src = src;
                                        document.body.appendChild(img);
                                    });
                            });
                        }); //获取 分割segments

                    });
                }
            });
        }

        function showImage(file, callback) {
            var reader = new FileReader();
            reader.onload = function () {
                callback(reader.result);
            }
            reader.readAsDataURL(file);
        }

        function imageResize(img, width, height, quality, callback) {
            var type = "image/jpeg";
            var
                canvas = document.createElement("canvas"),
                ctx = canvas.getContext("2d"); // quality = options.quality || 0.8; 
            canvas.width = width;
            canvas.height = height;
            ctx.drawImage(img, 0, 0, width, height);
            canvas.toBlob(callback, type, quality);
        }
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/bluelotos893/article/details/79661718