使用canvas實現對圖片的批量打碼


最近有個需求,利用h5的canvas對圖片一些涉及個人隱私的地方進行打碼再上傳,而且最好能實現批量打碼.意思是在一張圖片上對哪些地方做了打碼,后續的所有圖片都在同樣的地方也可以自動打上碼,不用人工一張一張進行圖片塗抹了.

例如:

首先想到的是利用canvas的drawImage方法將圖片加載進來,然后在利用鼠標的點擊移動事件在畫布上面划線,很容易就實現了這個功能.但是當載入其他圖片的時候,之前畫的線就全部消失了,因為canvas使用drawImage方法后會清空畫布,所以這個方法只能對一張圖片進行打碼.

后來就琢磨能不能將圖片和塗鴉分開,不放在一個canvas里面,將兩個canvas重疊起來,大小一樣,暫時設定為canvas1和canvas2,canvas1在底層,用於載入圖片的容器,canvas2在上層,用於用戶的塗抹層,當用戶在canvas2上面進行塗抹的時候,因為canvas1和canvas2是完全重疊的,看起來就像是在圖片上塗抹一樣,塗抹完成之后,用戶點擊保存按鈕時,將canvas2轉化為image對象,然后使用canvas1的drawImage的方法將這個image對象加載近canvas1,於是canvas1就成了兩個canvas的結合畫面,然后在將canvas1轉為image對象保存起來即可,因為現在canvas2的畫布還沒有被清空,此時我們只需要在canvas1載入另外一張圖片,在點擊保存又能對這張圖片進行一模一樣的打碼工作了,后續只需要將所有需要打碼的圖片放入一個數組,利用for循環就能夠實現批量圖片打碼的工作了.

但是此方法對於所有的圖片的要求是大小必須一樣,因為項目對於打碼的圖片大都是來自於手機截圖,圖片大小都是一樣的,所以這個方法完全可以勝任此工作.

下面貼上源碼

js代碼

function Doodle() {
    this.mousePressed = false;//鼠標是否按下
    this.imgWidth = 300;
    this.imgHeight = "";
    this.lastX;
    this.lastY;
    this.cPushArray = [];//存儲畫布倉庫
    this.cStep = -1;//當前步數
    this.c1;//  圖片畫布
    this.ctx1;//canvas對象1
    this.c2;//塗鴉畫布
    this.ctx2;//canvas對象2
    this.importMuban = function(imgUrl) {//載入模板圖片,以此圖片的寬高比例來對后面所有的圖片做預設.
        var self = this;
        var image = new Image();
        image.src = imgUrl;
        $(image).load(function () {
            self.imgHeight = (300/image.width)*image.height;
            self.c1.height = self.imgHeight;
            self.c2.height = self.imgHeight;
            $(".canvas-box").css({
                width: 300,
                height: self.imgHeight
            });
            self.ctx1.drawImage(image, 0, 0, self.imgWidth, self.imgHeight);
        });
    };
    this.importImg = function(imgUrl) {//載入其他圖片
        var self = this;
        var image = new Image();
        image.src = imgUrl;
        $(image).load(function () {
            self.ctx1.drawImage(image, 0, 0, self.imgWidth, self.imgHeight);
        });
    };
    this.saveImg = function() {//保存圖片
        var self = this;
        var newImg = this.c2.toDataURL("image/png");
        var Img = new Image();
        Img.src = newImg;
        $(Img).load(function (){
            self.ctx1.drawImage(Img, 0, 0, self.imgWidth, self.imgHeight);
            var img = self.c1.toDataURL("image/png");
            var ele = document.createElement("img");
            ele.src = img;
            document.body.appendChild(ele);
        });
    };
    this.clearCanvas = function () {//清空畫布
        this.ctx2.clearRect(0,0,this.c1.width,this.c1.height);
    };
    this.Draw = function (x, y, isDown) {
        if (isDown) {
            this.ctx2.beginPath();
            this.ctx2.strokeStyle = $('#selColor').val();
            this.ctx2.lineWidth = $('#selWidth').val();
            this.ctx2.lineJoin = "round";
            this.ctx2.moveTo(this.lastX, this.lastY);
            this.ctx2.lineTo(x, y);
            this.ctx2.closePath();
            this.ctx2.stroke();
        }
        this.lastX = x;
        this.lastY = y;
    };
    this.cPush = function() {
        this.cStep++;
        if (this.cStep < this.cPushArray.length) { this.cPushArray.length = this.cStep; }
        this.cPushArray.push(document.getElementById('myCanvas2').toDataURL());
    };
    this.cUndo = function() {
        var self = this;
        if (self.cStep > 0) {
            self.cStep--;
            var canvasPic = new Image();
            canvasPic.src = self.cPushArray[self.cStep];
            canvasPic.onload = function () {
                console.log(self.cStep,self.cPushArray);
                self.ctx2.clearRect(0,0,self.c1.width,self.c1.height);
                self.ctx2.drawImage(canvasPic, 0, 0, self.imgWidth, self.imgHeight);
            }
        }
    };
    this.cRedo = function() {
        var self = this;
        if (self.cStep < self.cPushArray.length-1) {
            self.cStep++;
            var canvasPic = new Image();
            canvasPic.src = self.cPushArray[self.cStep];
            canvasPic.onload = function () {
                self.ctx2.clearRect(0,0,self.c1.width,self.c1.height);
                self.ctx2.drawImage(canvasPic, 0, 0, self.imgWidth, self.imgHeight);
            }
        }
    };
    this.initFn = function (cId1,cId2){
        var self = this;
        this.c1 = $(cId1)[0];
        this.c2 = $(cId2)[0];
        this.ctx1 = this.c1.getContext("2d");
        this.ctx2 = this.c2.getContext("2d");
        this.cPush();
        $(cId2).mousedown(function (e) {
            self.mousePressed = true;
            self.Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false);
            console.log("anxia")
        });
        $(cId2).mousemove(function (e) {
            if (self.mousePressed) {
                self.Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
            }
        });
        $(cId2).mouseup(function (e) {
            if (self.mousePressed) {
                self.mousePressed = false;
                self.cPush();
            }
        });
        $(cId2).mouseleave(function (e) {
            if (self.mousePressed) {
                self.mousePressed = false;
                self.cPush();
            }
        });
    }
}
$(function (){
    var aDoodle = new Doodle();
    aDoodle.initFn("#myCanvas1","#myCanvas2");
    $("#img1").click(function (){
        aDoodle.importMuban("img/1.jpg");
    });
    $("#img2").click(function (){
        aDoodle.importImg("img/2.jpg");
    });
    $("#img3").click(function (){
        aDoodle.importImg("img/3.jpg");
    });
    $("#img4").click(function (){
        aDoodle.importImg("img/4.jpg");
    });
    $("#img5").click(function (){
        aDoodle.importImg("img/5.jpg");
    });
    $("#undo").click(function (){
        aDoodle.cUndo();
    });
    $("#redo").click(function (){
        aDoodle.cRedo();
    });
    $("#clearDraw").click(function (){
        aDoodle.clearCanvas();
    });
    $("#saveImg").click(function (){
        aDoodle.saveImg();
    });
})

html代碼:

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="js/doodle.js"></script>
    <style type="text/css">
        select{color: #333;}
        .htmleaf-icon{color: #fff;}
        .canvas-box{
            width: 500px;
            height: 400px;
            margin: 0 auto;
            background-size: cover;
            background-repeat: no-repeat;
            border: 1px solid #ccc;
            position: relative;
        }
        #myCanvas1{
            position: absolute;
            top: 0px;
            left: 0px;
        }
        #myCanvas2{
            position: absolute;
            top: 0px;
            left: 0px;
            z-index: 3;
        }
        .htmleaf-content{
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="htmleaf-container">
        <div class="htmleaf-content bgcolor-3">
            <div align="center" id="bgImg" class="canvas-box">
                <canvas id="myCanvas1" width="300"></canvas>
                <canvas id="myCanvas2" width="300"></canvas>
            </div>
            <button class="btn btn-primary" id="clearDraw">清空畫布</button>
            線條寬度 : <select id="selWidth">
            <option value="1">1</option>
            <option value="3">3</option>
            <option value="5">5</option>
            <option value="7">7</option>
            <option value="9" selected="selected">9</option>
            <option value="11">11</option>
        </select>
            線條顏色 : <select id="selColor">
            <option value="black">黑色</option>
            <option value="blue" selected="selected">藍色</option>
            <option value="red">紅色</option>
            <option value="green">綠色</option>
            <option value="yellow">黃色</option>
            <option value="gray">灰色</option>
        </select>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="btn btn-primary" id="undo">上一步</button>
            <button class="btn btn-danger" id="redo">下一步</button>
            <button id="saveImg" id="saveImg">保存圖片</button>
        </div>
        <div style="text-align:center;">
            <button id="img1">載入模板圖</button>
            <button id="img2">圖片1</button>
            <button id="img3">圖片2</button>
            <button id="img4">圖片3</button>
            <button id="img5">圖片4</button>
        </div>
    </div>
</body>
</html>

我在此方法的基礎上又添加了改變線的像素和顏色的功能.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM