使用canvas实现对图片的批量打码

摘要:
最近,有人要求使用h5的画布打印和上传一些涉及个人隐私的地方,最好是实现批量打印。这意味着,在您对图像进行编码的地方,所有后续图像都可以在同一位置自动编码,而不是手动逐张涂抹每个图像。例如,第一个想法是使用画布的drawImage方法加载图片,然后使用鼠标单击并移动事件在画布上绘制线条。这个功能很容易实现。但是当加载其他图片时,之前绘制的线条

最近有个需求,利用h5的canvas对图片一些涉及个人隐私的地方进行打码再上传,而且最好能实现批量打码.意思是在一张图片上对哪些地方做了打码,后续的所有图片都在同样的地方也可以自动打上码,不用人工一张一张进行图片涂抹了.

例如:

使用canvas实现对图片的批量打码第1张

首先想到的是利用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({
                 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>

我在此方法的基础上又添加了改变线的像素和颜色的功能.

免责声明:文章转载自《使用canvas实现对图片的批量打码》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇代理和协议区别及应用生产环境 压测下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Canvas:绘制路径

Canvas:绘制路径 绘制路径   图形的基本元素是路径。路径是[通过不同颜色和宽度的线段或曲线相连形成的不同形状的]点的集合。一个路径,甚至一个子路径,都是闭合的。   使用路径绘制图形需要一些额外的步骤。 首先,你需要创建路径起始点。 然后你使用画图命令去绘制路径。 之后把路径进行封闭。 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。 函...

怎么获得当前点击的按钮的id名?

<body> <input id="t1" type="button" value='fff'> <input id="t2" type="button" value='fff'> <input id="t3" type="button" value='f...

旋转的太极图

1.创建一个画布,获取canvas节点   <canvas id="c" width="500" height="500"></canvas>//创建canvas节点 <script type="text/javascript"> var canvas = document.get...

使用html2canvas和jsPdf实现打印功能

最近做项目中,️遇到过实现模版打印功能,网上也找到很多资料可以实现,有的方式可以实现分页,但是打印的A4纸上下不能留边距,后来找到一个通过剪裁的方式可以实现左右上下留边距,并且能实现分页; 方法如下:基本思路是对获得的canvas进行切割,按A4纸大小并留边距后的比例进行剪裁,切出一页一页的内容来,再分别加到pdf中。 DEMO: 1 // 导出页面为...

WPF 中动态创建和删除控件

动态创建控件 1.容器控件.RegisterName("Name",要注册的控件) //注册控件 2.容器控件.FindName("Name") as 控件类型 //找到控件并转换成相应类型 注意:仅通过 控件.Name来设置是不能通过FindName来找到控件的,必须注册 动态删除控件1.容器控件.Children.Remove(控件) //移除控件 2...

走进WPF之UI布局

一个成功的软件,离不开人性化的UI设计,如何抓住用户第一视觉,让用户产生依赖感,合适优雅的布局必不可少。本文以一些简单的小例子,简述WPF中布局面板控件的使用,仅供学习分享使用,如有不足之处,还请指正。 涉及知识点 在WPF中,关于布局面板控件,主要有以下几种: StackPanel:栈面板,可以将元素排列成一行或者一列。其特点是:每个元素各占一行或者一...