一,前端合成带水印的图片

一般来说,生成带水印的图片由后端生成,但不乏有时候需要前端来处理。当然,前端处理图片一般不建议,一方面js的处理图片的方法不全,二是有些老版本的浏览器对canvas的支持度不够。

下面我们就说说,利用canvas 生成带水印的图片。

1、我们要实现一下效果

2、创建一个canvas

var canvas = document.createElement('canvas');var time = new Date();var logoCanvas =time+'  '+'http://www.cnblogs.com/zuoan-oopp'; // 水印var context = canvas.getContext('2d');

3,绘制图片

var imgUpload = new Image();imgUpload.src =src;imgUpload.onload = function () {context.drawImage(imgUpload, 0, 0,imgUpload.width,imgUpload.height,0,0,imgWidth,imgHeight);
}

4,按照1024*768的比例压缩图片

var width = imgUpload.width;var height= imgUpload.height;var scale,imgWidth,imgHeight;  // 缩放比 ,按照1024*768缩放if(width>height){  // 横着拍if(width>1024){   //宽大于1024scale = 1024/width;imgWidth =1024;imgHeight = height*scale;  // 算出按照宽1024,的等比压缩后的高if(imgHeight>768){        // 若高>768,算出等比768缩放的宽scale = 768/imgHeight;imgHeight = 768;imgWidth = imgWidth*scale;}}else{imgWidth = width;imgHeight = height}}else{     // 纵着拍的或者正方形if(height>1024){ // 高大于1024scale = 1024/height;imgHeight =1024;imgWidth = width*scale;  // 算出按照宽1024,的等比压缩后的高if(imgWidth>768){        // 若高>768,算出等比768缩放的宽scale = 768/imgWidth;imgWidth = 768;imgHeight = imgHeight*scale;}}else{imgWidth = width;imgHeight = height}}

5,给canvas添加背景和水印

canvas.height = imgHeight+60;  // 给canvas 赋值高度
            context.save();context.fillStyle = "green";context.fillRect(0,0,imgWidth,imgHeight+60);  // 绘制图片的背景
            context.restore();context.save();context.font="100px PingFangSC-Regular microsoft yahei";context.fillStyle = "#000";context.restore();

6,如果水印文字太长要换行,代码如下:

for(let i=0;i<logoCanvas.length;i++){  // 字数换行lineWidth+=context.measureText(logoCanvas[i]).width; if(lineWidth>canvas.width-20){ context.fillText(logoCanvas.substring(lastSubStrIndex,i),10,initHeight);//绘制截取部分initHeight+=20;//20为字体的高度height+=20;lineWidth=0;lastSubStrIndex=i;} if(i==logoCanvas.length-1){//绘制剩余部分context.fillText(logoCanvas.substring(lastSubStrIndex,i+1),10,initHeight);}}

7,canvas转换成base64位,以图片的形式展示

var url=canvas.toDataURL("image/jpg", 0.8);   // canvas转换成base64位var newImg = new Image(); newImg.src = url;newImg.onload = function() {document.getElementById('imgUpload').append(newImg);};

注意:toDataURL函数可能会出现跨域的问题,请在同一个服务器下操作

二,图片上传

1,图片上传到服务器要转换成文档流(二进制blob)的形式。所以无论上传canvas,还是img,要先转换成文档流

2、canvas 转换成文档流,利用toBlob方法转换

canvas.toBlob(function(blob) {//创建formevar form = new FormData();form.append('file', blob); $.POST(url, {data:formData,processData: false,contentType: false,}).done(function(data) {console.log('回调函数')}).fail((data,textStatus)=>{console.log('失败函数')})});

注意:次方法兼容性不太好,,低版本的chrome不支持,安卓4.4.2版本都不支持(只测了这一个版本),各浏览器的兼容性如下:

3,canvas 直接转换成文档流兼容性不太好,但是这个功能又必须做,怎么办,,,那么我们就换种方式,,使用base64位上传。

4,除了base64位上传,还想使用blob二进制文档流上传,怎么办。。。我们可以使用window对象提供的atob函数

5、WindowOrWorkerGlobalScope.atob()函数用来解码一个已经被base-64编码过的数据。你可以使用 window.btoa() 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 window.atob() 方法来将数据解码。

6,将base64位转换成blob,这样就可以避免低版本的chrome不支持了。

url = url.replace("data:image/png;base64,", "");var blob = b64toBlob(src);var formData = new FormData();formData.append("file",blob);$.POST(url, {data:formData,processData: false,contentType: false,}).done(function(data) {console.log('回调函数')}).fail((data,textStatus)=>{console.log('失败函数')})// 将base64位转换成blobfunction b64toBlob(b64Data, contentType, sliceSize) {contentType = contentType || '';sliceSize = sliceSize || 512;var byteCharacters = atob(b64Data);var byteArrays = [];for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {var slice = byteCharacters.slice(offset, offset + sliceSize);var byteNumbers = new Array(slice.length);for (var i = 0; i < slice.length; i++) {byteNumbers[i] = slice.charCodeAt(i);}var byteArray = new Uint8Array(byteNumbers);byteArrays.push(byteArray);}var blob = new Blob(byteArrays, {type: contentType});return blob;}

ablob兼容性如下:

 三,源代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>合成水印</title><script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script><style type="text/css">*{margin:0;padding:0;}.content{display:block;margin: 30px;}.content:after{content: "";display:block;clear:both;}.content li{float: left;margin-left:30px;list-style: none;}.img-wrap{display:-webkit-box;-webkit-box-align:center;-webkit-box-pack: center;width:500px;height:400px;}.img-wrap img{max-width: 100%;max-height:100%;}.img-wrap canvas{max-width: 100%;max-height:100%;}</style>
</head>
<body><ul class="content"><li><p>原图</p><div class="img-wrap"><img src="2.jpg"/></div></li><li><p>加水印的canvas</p><div id="imgContent" class="img-wrap"></div></li><li><p>加水印的img</p><div id="imgUpload" class="img-wrap"></div></li></ul><script type="text/javascript">var src = $('img').attr('src');var canvas = document.createElement('canvas');var time = new Date();var logoCanvas =time+'  '+'http://www.cnblogs.com/zuoan-oopp'; // 水印var context = canvas.getContext('2d');// 这是上传图像var imgUpload = new Image();imgUpload.src =src;imgUpload.onload = function () {// 绘制var width = imgUpload.width;var height= imgUpload.height;var scale,imgWidth,imgHeight;  // 缩放比 ,按照1024*768缩放if(width>height){  // 横着拍if(width>1024){   //宽大于1024scale = 1024/width;imgWidth =1024;imgHeight = height*scale;  // 算出按照宽1024,的等比压缩后的高if(imgHeight>768){        // 若高>768,算出等比768缩放的宽scale = 768/imgHeight;imgHeight = 768;imgWidth = imgWidth*scale;}}else{imgWidth = width;imgHeight = height}}else{     // 纵着拍的或者正方形if(height>1024){ // 高大于1024scale = 1024/height;imgHeight =1024;imgWidth = width*scale;  // 算出按照宽1024,的等比压缩后的高if(imgWidth>768){        // 若高>768,算出等比768缩放的宽scale = 768/imgWidth;imgWidth = 768;imgHeight = imgHeight*scale;}}else{imgWidth = width;imgHeight = height}}canvas.width = imgWidth;    // geicanvas赋值宽度canvas.height = imgHeight+60;  // 给canvas 赋值高度
            context.save();context.fillStyle = "green";context.fillRect(0,0,imgWidth,imgHeight+60);  // 绘制图片的背景
            context.restore();context.save();context.font="100px PingFangSC-Regular microsoft yahei";context.fillStyle = "#000";context.restore();context.drawImage(imgUpload, 0, 0,imgUpload.width,imgUpload.height,0,0,imgWidth,imgHeight);var lineWidth = 0var initHeight=imgHeight+30;//绘制字体距离canvas顶部初始的高度var lastSubStrIndex= 0; //每次开始截取的字符串的索引     for(let i=0;i<logoCanvas.length;i++){  // 字数换行lineWidth+=context.measureText(logoCanvas[i]).width; if(lineWidth>canvas.width-20){ context.fillText(logoCanvas.substring(lastSubStrIndex,i),10,initHeight);//绘制截取部分initHeight+=20;//20为字体的高度height+=20;lineWidth=0;lastSubStrIndex=i;} if(i==logoCanvas.length-1){//绘制剩余部分context.fillText(logoCanvas.substring(lastSubStrIndex,i+1),10,initHeight);}}var url=canvas.toDataURL("image/jpg", 0.8);   // canvas转换成base64位var newImg = new Image(); newImg.src = url;newImg.onload = function() {document.getElementById('imgUpload').append(newImg);};document.getElementById('imgContent').append(canvas);  // 将canvas绘制的图片存放在imgContent里
        };canvas.toBlob(function(blob) {//创建formevar form = new FormData();form.append('file', blob); $.POST(url, {data:formData,processData: false,contentType: false,}).done(function(data) {console.log('回调函数')}).fail((data,textStatus)=>{console.log('失败函数')})});url = url.replace("data:image/png;base64,", "");var blob = b64toBlob(src);var formData = new FormData();formData.append("file",blob);$.POST(url, {data:formData,processData: false,contentType: false,}).done(function(data) {console.log('回调函数')}).fail((data,textStatus)=>{console.log('失败函数')})// 将base64位转换成blobfunction b64toBlob(b64Data, contentType, sliceSize) {contentType = contentType || '';sliceSize = sliceSize || 512;var byteCharacters = atob(b64Data);var byteArrays = [];for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {var slice = byteCharacters.slice(offset, offset + sliceSize);var byteNumbers = new Array(slice.length);for (var i = 0; i < slice.length; i++) {byteNumbers[i] = slice.charCodeAt(i);}var byteArray = new Uint8Array(byteNumbers);byteArrays.push(byteArray);}var blob = new Blob(byteArrays, {type: contentType});return blob;}</script>
</body>
</html>

四,参考文档

1、https://developer.mozilla.org/zh-CN/docs/Web/API/WindowBase64/atob

2、https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob

转载于:https://www.cnblogs.com/zuoan-oopp/p/8006524.html

使用canvas给图片添加水印, canvas转换base64,,canvas,图片,base64等转换成二进制文档流的方法,并将合成的图片上传到服务器,...相关推荐

  1. CAJ转换成Word文档用什么方法

    大家在职场办公中,可能会遇到CAJ转Word的转换问题,因为CAJ文件我们很少用到,所以当遇到这个问题时,可能都会被难住了,所以,今天给大家分享一个新的方法,CAJ转换成Word文档的有效方法,希望可 ...

  2. 怎么把图片文字转换成word文档?这个方法了解一下

    在现代的生活中,我们经常需要将图片中的文字转换成Word文档,以方便我们编辑和处理文本.虽然在电脑上进行这项工作很容易,但是在手机上可能会有些困难.在本文中,我们将介绍一些在手机上将图片文字转换成Wo ...

  3. 将扫描图片转换成word文档用什么方法

    有了工作经验的朋友都知道,想要在pdf文档中添加或编辑内容不是那么简单的,特别是扫描的pdf文件,想要编辑就得用到文字识别软件了. 首先在电脑中安装好文字识别软件:捷速OCR文字识别软件是一款超级无敌 ...

  4. java 转换上传文档_自己编写JAVA环境下的文件上传组件 (转)

    客户端上传后,端的数据流头尾部格式如下,这里上传了一个文档 我们看看数据流的头部: -----------------------------7d22f821706e0Content-Disposit ...

  5. 水晶报表使用经验谈1--建立水晶报表第一步及编译最易出现错误的解决方法及报表转换成pdf文档进行打印方法...

    初用水晶报表(vs .net2003集成,版本Version=9.1.5000.0) 装好后要注册 注册号:6707437608 密码:AAP5GKS0000GDE100DS 想要在.aspx文件中使 ...

  6. 如何把图片扫描成word文档?

    在我们工作学习中,难免会遇到需要整理图片中的文字信息.而想要快速的整理出图片中的文字,就需要使用到一些工具来辅助我们,毕竟我们不可能一个个去手动输入,这会很麻烦又浪费我们的时间.那么如何把图片扫描成w ...

  7. java xml转html_如何在Java中将XML文档转换成HTML文档.pdf

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp网页设计/UI 如何在Java中将XML文档转换成HTML文档. ...

  8. ​PDF如何转换成Word文档?分享两种好用的转换方法

    怎么把PDF文件转换成Word文档呢?大家在工作中相信都会使用这两种格式的 文件,对于这两种格式的文件优劣处大家也很清楚,一个适合用来发送文件,一个适合用来编辑文件,如果我们接收到一份PDF文件,想要 ...

  9. PPT怎么转换成Word文档?分享两种转换小妙招

    怎么把PPT文件转换成Word文档呢?大家在日常的工作中经常会有转换文件格式的需求,将文件转换成Word文档格式也是比较常见的.当我们遇到需要将PPT文件转换成Word文档格式,该怎么才能做到呢?今天 ...

最新文章

  1. 九丶青龙运行聚看点教程
  2. 常用的函数式接口_Consumer接口
  3. MonkeyFest2018 微软最有价值专家讲座
  4. 若依前后端部署之后验证码不显示
  5. 对象失去焦点时自己动提交数据
  6. delphi BLE 后台
  7. L1-030 一帮一 (15 分)—团体程序设计天梯赛
  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_02 递归_3_练习_使用递归计算阶乘...
  9. Git小乌龟(TortoiseGit)使用详情
  10. 利用MEGA做序列比对
  11. 地图导航定位二维码如何制作呢?
  12. 2021-2027全球及中国油田钻机行业研究及十四五规划分析报告
  13. 亚马逊SP-API接口申请对外公开可发布教程
  14. 快速在网站跳转支付宝付款链接
  15. Linux--用xmanager远程管理的设定过程
  16. html转图片/html2canvas的使用/星座测试/类似于损友圈的活动
  17. 直播预告 | 双十一电商风控怎么破,看这场直播就对了!
  18. 【iOS逆向与安全】iOS插件开发光速入门
  19. (附源码)小程序记账微信小程序 毕业设计180815
  20. 【程序设计】定时任务调度平台需求说明书

热门文章

  1. 详细解说MySQL中BLOD和TEXT字段类型二者概念及区别
  2. 眼缺的出现的不懂的错误
  3. 抢红包算法--四种抢红包算法对比
  4. oracle ioc图标,如何在PPT中导入ico格式的图标
  5. linux服务开机启动chkconfig,Linux开机服务自启动之chkconfig命令详解
  6. 淘派上架预告 | 郑燕作品 12.21 20:00开售
  7. java编程 问题_Java编程常见问题汇总
  8. 基于Java的青年公寓租赁系统(毕设)
  9. # 2021-01-11 #「GNOME」- 启用系统托盘图标(System Tray)
  10. 误操作导致引导区崩溃的补救办法(需要使用火绒预备份引导区)