最近有个需求,利用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>

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

使用canvas实现对图片的批量打码的更多相关文章

  1. 基于HTML5 Canvas实现的图片马赛克模糊特效

    效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...

  2. canvas生成遮罩图片

         首先我们知道css3中增加了不少好用.好玩的css3样式可以使用.今天我们要说到是遮罩.        它的使用方式也不复杂,和background使用方式差不多.使用mask-image就 ...

  3. HTML5 Canvas前台压缩图片并上传到服务器

    1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...

  4. [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)

    接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...

  5. 用canvas给视频图片添加特效

    Canvas制作视频图片特效 1. Canvas介绍 1.1Canvas是html5上的一个画布标签,功能有点类似java的swing.可以在canvas上画线条 弧线, 文字 就是画布的功能. 具体 ...

  6. Python3.7 练习题(三) 将指定目录下的图片进行批量尺寸大小处理

    # 将指定目录下的图片进行批量尺寸大小处理 #修改图片尺寸 导入Image os 快捷键 alt+enter import os from PIL import Image def process_i ...

  7. 微信小程序--canvas画布实现图片的编辑

    技术:微信小程序   概述 上传图片,编辑图片大小,添加文字,改变文字颜色等 详细 代码下载:http://www.demodashi.com/demo/14789.html 概述 微信小程序--ca ...

  8. canvas 2.0 图片绘制

    绘制图片drawImage 2013.02.21 by 十年灯·一条评论 本文属于<html5 Canvas画图系列教程> 这里的绘制图片是指把一张现成的图片,绘制到Canvas上面. 有 ...

  9. C++ 根据图片url 批量 下载图片

    最近需要用到根据图片URL批量下载到本地的操作.查找了相关资料,记录在这儿. 1.首先在CSV文件中提取出url ifstream fin("C:\\Users\\lenovo\\Deskt ...

随机推荐

  1. 亲爱的SAP从业者们,烦请做个SAP知识学习种类的小调查

    "世上再也没有比时钟更加冷漠的东西了:在您出生的那一刻,在您尽情地摘取青春幻梦的花朵的时刻,它都是同样分秒不差地滴答着." -- 高尔基 2019年马上又要离我们而去了,从2018 ...

  2. HTML左边盒子固定,右边盒子自适应

    html: <div class="box1"> <div class="divA">DIVA</div> <div ...

  3. hiho #1144 : 01串(模拟)

    #1144 : 01串 时间限制:7000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个整数n和m,求是否存在恰好包含n个0和m个1的01串S,使得S中不存在子串"001 ...

  4. Tomcat非root身份运行制作Linux系统服务管理

    理论知识怱略,马上开始实战 一.首先准备好tomcat 启动.关闭.重启Shell脚本: 以下Shell脚本主要修改值 tomcatPath:tomcat目录 runUser:以哪个身份运行 此处测试 ...

  5. 28. ClustrixDB 分布式架构/评估模型

    本节描述如何在数据库中计算查询.在ClustrixDB中,我们跨节点切片数据,然后将查询发送到数据.这是数据库的基本原则之一,它允许随着添加更多节点而几乎线性地扩展. 有关如何分布数据的概念,请参阅数 ...

  6. ping —— 虚拟机

    1. 主机ping 虚拟机 ping 不通    设置——虚拟机—— 防护墙——入站规则——  文件和打印共享 (回显请求-ICMPv4-In) 2.主机连接不上虚拟机中的sqlsrver   设置— ...

  7. javascript中继承方式及优缺点(三)

    文以<JavaScript高级程序设计>上的内容为骨架,补充了ES6 Class的相关内容,从我认为更容易理解的角度将继承这件事叙述出来,希望大家能有所收获. 1. 继承分类 先来个整体印 ...

  8. Trie树(字典树)整理

    字典树 (Trie) 用于存储字符串.树的每条边恰好表示一个字符,每个节点代表从根到该节点的路径所对应的字符串. 简介与操作实现可见蓝书P82~83. Trie字典树很好地利用了前缀,节省了很多空间. ...

  9. kmeans与kmeans++的python实现

    一.kmeans聚类: 基本方法流程 1.首先随机初始化k个中心点 2.将每个实例分配到与其最近的中心点,开成k个类 3.更新中心点,计算每个类的平均中心点 4.直到中心点不再变化或变化不大或达到迭代 ...

  10. css彩色(渐变)文字

    css彩色文字也称渐变文字 在张鑫旭博客首页看到这效果,就自己研究了一下. 实现方法加个背景然后在根据文本剪切,再把文本填充为透明色让之前设置的背景颜色显示出来即可. -webkit-backgrou ...