阮一峰的详解

  • 一个demo 彻底明确fileReader的应用 demo预览
  • demo 在move的时候的地位还须要进一步进行相干的计算,当初的地位计算出错了
<!DOCTYPE html><html lang="en"><head>    <title>fileReader + canvas 预览剪切demo</title>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <style>        canvas {            border: 1px solid red;        }        .mergeBox {            display: inline-block;            position: relative;            width: 200px;            height: 200px;            z-index: 0;            top: 0;            overflow: hidden;        }        #mergeCanvas {            position: absolute;            top: 0;            left: 0;            z-index: 0;            width: 200px;            height: 200px;        }        .mergeDiv {            display: none;            position: absolute;            z-index: 0;            top: 0;            left: 0;            width: 200px;            height: 200px;            background-image: url('http://qinyuanqiblog.github.io/images/angular/shape_lingxing.png');            background-repeat: no-repeat;            background-size: 200px, 200px;        }        label {            display: block;            width: 100px;            height: 50px;            font-size: 20px;            color: #fff;            line-height: 50px;            background: #999;            cursor: pointer;            text-align: center;            border-radius: 10px;        }        input[type='file'] {            display: none;        }        .preview-area {            display: none;        }    </style></head><body>    <label for="file">抉择文件</label>    <input id="file" type="file" accept="image/*">    <div class="preview-area">        <canvas id="previewCanvas"></canvas>        <canvas id="compareCanvas"></canvas>        <button class="merge">合成</button>        <button class="inverse">反色</button>        <div class="mergeBox">            <canvas id="mergeCanvas"></canvas>            <div class="mergeDiv"> </div>        </div>        <canvas id="clipCanvas"></canvas>        <button class="clip">确认裁剪</button>        <img src="" class="makePreview" alt="">    </div></body><script>    /** 思路     *     * 1.  应用fileReader API 读取到图片     * 2.  生成previewCanvas预览图片     * 3.  在previewCanvas上解决图片的滤镜和裁剪     * 3.1 在previewCanvas上进行图片滤镜解决(canvas的像素级解决)     * 3.2 把须要截取的图像写入到compareCanvs上,之后再和previewCanvas比照, 生成clipCanvas(裁剪图片之后的canvas)     * 3.3 在clipCanvas上进行拖动并生成预览     * 3.3.1  图片平移这一块应用到了css3的 matrix 相干的常识 其实也能够应用定位来实现的,起初的这个版本我就改用了定位来做的     *        transform:matrix(a,b,c,d,e,f)     *          a 程度缩放 (1)     *          b 程度歪斜 (0)     *          c 垂直歪斜 (0)     *          d 垂直缩放 (1)     *          e 程度位移 (0)     *          f 垂直位移 (0)     * 3.4 把clipCanvas上的图片转换成blob对象的地址 并生成预览图片     *     */    var input = document.querySelector('input');    var previewCanvas = document.querySelector('#previewCanvas');    var compareCanvas = document.querySelector('#compareCanvas');    var mergeCanvas = document.querySelector('#mergeCanvas');    var clipCanvas = document.querySelector('#clipCanvas');    var previewCtx = previewCanvas.getContext('2d');    var compareCtx = compareCanvas.getContext('2d');    var mergeCtx = mergeCanvas.getContext('2d');    var clipCtx = clipCanvas.getContext('2d');    var mergeDiv = document.querySelector('.mergeDiv');    var inverse = document.querySelector('.inverse');    var merge = document.querySelector('.merge');    var clip = document.querySelector('.clip');    var previewWidth = compareCanvas.width = previewCanvas.width = 200;    var previewHeight = compareCanvas.height = previewCanvas.height = 200;    var isDrag = false;    var disX = 0;    var disY = 0;    var clipDx = 0;    var clipDy = 0;    var previewImg = null;    var compareImg = null;    clipCanvas.width = previewWidth;    clipCanvas.height = previewHeight;    //读取文件    input.addEventListener('change', readerFile);    //生成比照图    function createCompareImg() {        compareImg = new Image();        compareImg.crossOrigin = "Anonymous"; //解决跨域        compareImg.src = 'http://qinyuanqiblog.github.io/images/angular/shape_lingxing.png';        compareImg.onload = function() {            compareCtx.drawImage(this, 0, 0, previewWidth, previewHeight);        }    }    //读取文件,生成canvas预览    function readerFile() {        var file = this.files[0];        // FileReader API用于读取文件,即把文件内容读入内存        var reader = new FileReader();        //读取文件胜利        reader.onload = function() {            createPreviewToCanvas(reader.result);        }        //返回一个基于Base64编码编码的数据URI对象        reader.readAsDataURL(file);    }    /**     * 生成canvas预览图,不便后续解决     * @param dataURL {object}        一个基于Base64编码编码的数据URI对象     */    function createPreviewToCanvas(dataURL) {        previewImg = new Image();        previewImg.src = dataURL;        previewImg.onload = function() {            previewCtx.drawImage(previewImg, 0, 0, previewWidth, previewHeight);        }        createCompareImg();        document.querySelector('.preview-area').style.display = 'block';    }    //合并图片    merge.addEventListener('click', function() {        mergeDiv.style.display = 'block';        mergeCanvas.width = previewWidth;        mergeCanvas.height = previewHeight;        mergeCtx.drawImage(previewImg, 0, 0, previewWidth, previewHeight);    });    //滤镜解决    inverse.addEventListener('click', function() {        var previewData = previewCtx.getImageData(0, 0, previewWidth, previewHeight);        for (var i = 0; i < previewData.data.length; i += 4) {            previewData.data[i] = 255 - previewData.data[i];            previewData.data[i + 1] = 255 - previewData.data[i + 1];            previewData.data[i + 2] = 255 - previewData.data[i + 2];            previewData.data[i + 3] = 255;        }        previewCtx.putImageData(previewData, 0, 0);    })    mergeDiv.addEventListener('mousedown', mouseDownFn);    mergeDiv.addEventListener('mousemove', mouseMoveFn);    mergeDiv.addEventListener('mouseup', mouseUpFn);    mergeDiv.addEventListener('mouseleave', mouseUpFn);    //裁剪图片    clip.addEventListener('click', createClipPreview);    //查看剪切之后的图片    function createClipPreview() {        clipImg(clipDx, clipDy)        var imgSrc = _base64ToBlob(clipCanvas.toDataURL());        document.querySelector('.makePreview').src = imgSrc;    }    /**     * base64编码数据转成blob对象     * @param dataURL {object}        一个基于Base64编码编码的数据URI对象     * @return result {blob object}   返回一个能够间接浏览的本地图片地址      */    function _base64ToBlob(dataURL) {        //获取源数据类型        var mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0];        //取到base64转码后的源数据        var str = dataURL.split(',')[1];        //base64解码        str = window.atob(str);        //应用一个 Uint8Array 来存放数据        var utf8Array = new Uint8Array(str.length);        for (var i = 0; i < str.length; i++) {            utf8Array[i] = str.charCodeAt(i);        }        //转换成一个blob对象        var blob = new Blob([utf8Array], {            type: mimeString        });        //生成能够间接拜访的本地地址        var src = URL.createObjectURL(blob);        return src;    }    //裁剪图片    function clipImg(dx, dy) {        var proviewImgData = previewCtx.getImageData(-dx, -dy, previewWidth, previewHeight);        var compareImgData = compareCtx.getImageData(0, 0, previewWidth, previewHeight);        for (var i = 3; i < compareImgData.data.length; i += 4) {            if (compareImgData.data[i] !== 0) {                proviewImgData.data[i] = 0;            }        }        clipCtx.putImageData(proviewImgData, 0, 0);    }    var mergeCanvasLeft = 0;    var mergeCanvasTop = 0;    function mouseDownFn(e) {        var event = e || ev;        disX = event.offsetX;        disY = event.offsetY;        mergeCanvasLeft = mergeCanvas.style.left == false ? 0 :  mergeCanvas.style.left;        mergeCanvasTop =  mergeCanvas.style.top == false ? 0 : mergeCanvas.style.top;        isDrag = true;    }    function mouseMoveFn(e) {        if (isDrag) {            var event = e || ev;            var left = event.offsetX - disX + parseInt(mergeCanvasLeft);            var top = event.offsetY - disY + parseInt(mergeCanvasTop);            //也能够应用矩阵或者是translate 来做, 我当初的做法是改成了定位的模式            // mergeCanvas.style.transform = 'matrix(1,0,0,1,' + left + ',' + top + ')';            mergeCanvas.style.left = left + 'px';            mergeCanvas.style.top = top + 'px';            // 裁剪图片 生成预览图            clipImg(left, top);            //裁剪地位管制            clipDx = left;            clipDy = top;        }    }    function mouseUpFn() {        isDrag = false;    }</script></html>