canvas图像模糊以及图像变形难题,保存图像以及存在的标题

By admin in 4858美高梅 on 2019年4月9日

相遇的标题:Retina屏上字体线条模糊难题

近些年帮高校官方微信做了一个头像合成的小页面,用户能够团结挑选地面照片,上传并裁剪后,与全校logo合成最后图片,用户能够长按保存到本地,同样,作者也把他放到了GitHub,效果大致上面这几个样子。因为有法定微信的加大,点击量分分钟过五千,固然是个很一般的事物,本身写的代码也很相似,都以望着朋友圈很两个人用着通过协调写的制作器做的头像,感觉很棒哦。

第二HTML5中新增画布标签<canvas></canvas>,所以有个别老版本的浏览器是不帮忙的

难题:有时用canvas作图时意识图像会并发模糊不清楚的标题,甚至做出来的图彰显出的机能与大家给的数值所应有突显出的功能分化

缓解方案:放大canvas的高低,然后用css压缩回原大小,例如:想要900*400的画布,先将画布设置为
width=”1800px” height=”800px”,再用css {width: 900px;height:
400px;}压缩。

4858美高梅 1

运用canvas标签须要明白以下几点:

案由:当您在支撑html5canvas的浏览器下查看页面包车型大巴时候,canvas画布的暗许大小是300*150,也正是一张图纸,当在css设置画布大时辰比如350*350实在是将原画布(300*150)举办了拉伸,所以会促成图像变形,至于模糊的题材与浏览器处理
canvas 的点子有关

 

test.gif

一.须要在HTML文书档案中指明canvas标签,在canvas标签中要求写1些提醒新闻

图像变形化解措施:将想要设置的画布大小直接设置在canvas标签上

最终效果如下图:

那个页面全体在前者达成,因为HTML伍的雄强,小编没写一句后台代码,其余非凡感激这么雅观的开源项目Cropper.js,为大家提供了那般好的剪裁插件。但是在做的经过中,仍然碰到了多如牛毛标题,越发是canvas绘的图在手提式无线电话机等高分辨率设备上,会变模糊的题材,所以仍然有不能缺少总计一下。

<canvas id=”canvas” width=”500″ height=”500″>

          <canvas  id=”mycanvas” width=”350px”
height=”350px”></canvas>

4858美高梅 2

Canvas绘图API使用

canvas图像模糊以及图像变形难题,保存图像以及存在的标题。有关canvas的别的文化自行查阅API,后天平素上手canvas绘制图像。你必要领会
一.canvas的width和height 和css 的width和height不是三回事

4858美高梅 3

image.png

4858美高梅 4

image.png

能够见见canvas的css
width,height分别为400px,画布width,height为200,200是把css像素分成了200份,所以填充宽度为100,却占了csswidth的3/陆.
结论(假如cx指画布长度单位)

  1. canvas画布的默许宽高300*150
  2. css
    width和height决定你在显示器上占多大空间,在您不设置的时候,默许和画布大小同等
  3. 当你的css宽高和画布宽高不均等时,会有2个兑换关系,这会导致部分奇怪的难点。比如说css
    width:450px;height:300px;
    画布未有设置的话。暗中同意300cx150cx,所以水平方向一cx=450/300=壹.5px
    垂直方向一cx=300/150=2px
    。所以您这一年画二个拾0
    十0的纺锤形,画出来的是一.5100,2100的圆柱形,人家本来是大家数学里学的专业坐标轴,你强行令人家单位长度分裂了。所以若是未有要求,不要改动canvas的css
    width和height,那时候1cx=一px,而且档次方向和垂直方向是一样的,假若你非要改,起码让她们比例相同,即水平方向一cx对等多少个px,在笔直方向保持一致
  4. 在canvas里绘图,用到的有着长度单位都以指cx.默许情状下,一cx=一px.

二.看绘图上下文提供的连带API

  1. context.drawImage(image,x,y)
    x,y为画布中画图的发端坐标,用此方法绘制出的图像与原图大小同等,即只要图片尺寸为640320,那么即640cx320cx,默认cx=px

  2. context.drawImage(image,x,y,w,h)
    w,h指绘制出来的图像的宽窄与高度,比例与原图宽高最佳同一,图像不会变形。

  3. context.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh);
    此方法可用来绘制图像的一部分区域,sx,sy为壹些区域的开头点坐标,sw,sh为部分区域的宽高。(sx,sy,sw,sh)
    与(dx,dy,dw,dh)未有关系,前者表示从何地截取,取多大,后者表示你要在哪个地方放,在多大的地方放,可以放大也许裁减。如能够用于局地放大,完成特写效果
    上述格局中的image 均指image对象

    var img=new Image();
    img.src="" //指定url
    img.onload=function(){
       //绘制图像
    }
    

叁.兑现图像组合
用canvas完成图像组合也很不难,能够经过设置图形上下文的globalCompositeOperation
属性来决定图像组合情势
如笔者落成那一个图像合成的成效,笔者想要的logo不动,然后用户图像绘制在其江湖。

4858美高梅 5

image.png

另外格局还有为数不少,请自行查阅API
肆.怎样将canvas绘制的图形保存成图片
实际canvas绘制的任陈菲西都足以保存为图片,代码也很简单

var oCanvas=document.getElementById("myCanvas");
var src=oCanvas.toDataURL("image/png") ;
//然后你就可以随便怎么利用,你可以利用HTML5 a标签 download属性,也可以将其通过img标签展示到
//页面,然后长按/右键保存到本地

  您的浏览器不帮助Canvas

图像模糊的缓解方法:将canvas的绘图进度放大两倍(也能够依照自个儿须求加大其余倍数,小编在品种中加大了四倍才感觉舒心些,依据项目要求),然后将canvas的父元素收缩两倍(依据绘制进程中加大的翻番分明了,当打几倍父成分就减弱几倍)就能够缓解canvas图像模糊难点,

代码:

动用canvas在高清屏绘制图像的大坑

一开首并未有意识那几个难题,可是发给外人头像制作器的链接,外人跟自身说变化的头像太模糊了,作者自个儿试了下,的确很模糊,于是就百度了下,幸而那是一个明了的坑,所以一百度就找到了消除办法。
并发那么些题材的原因即使,在四哥大等高清屏设备上,存在一个devicePixelRatio,这么些事物对于搞活动端web开发依旧相比较主要的,你在支付移动端网页是,初始平时会写三个name为viewport的价签也与那几个事物有关。详情请看作者的移步端支出必须掌握的viewport
化解办法也相当粗略,先通过hidpi-canvas-polyfill提供的函数得到PixelRatio

var getPixelRatio = function(context) {
var backingStore = context.backingStorePixelRatio ||
    context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio || 1;
    return (window.devicePixelRatio || 1) / backingStore;
};

然后,将canvas画布宽高先增加PixelRatio
倍,然后再用css将宽高缩短到原来的宽高。经测试,当原图比画布大小大时,此方法比并非此办法清晰的多,当原图大小与canvas大小相同时,那几个题材不是很让人惊叹。

</canvas>

  .box{zoom:0.5;}

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>echarts绘制</title>
  6 </head>
  7 <body>
  8     <canvas id="canvas" width="1800px" height="800px" style="border: 1px solid #ebebed;width: 900px;height: 400px;"></canvas>
  9     <script>
 10         var scale = 2;
 11         var canvas = document.getElementById('canvas');
 12         var config = {
 13             width: canvas.width,
 14             height: canvas.height,
 15             Left: 70,
 16             Top: 90,
 17             Right: 30,
 18             Bottom: 60,
 19             color: ["#5266d7"],
 20             yLine:{
 21                 splitcount: 8,
 22                 data:[0,100,200,300,400,500,600,700,800]
 23             },
 24             xLine:{
 25                 splitcount: 9,
 26                 data:[1,2,3,4,5,6,7,8,9,10]
 27             },
 28             series:{
 29                 data:[0, 532, 555, 700, 500, 800, 300, 270, 358, 160, 453, 577, 639, 758, 233, 299, 120, 188, 158, 176, 333, 257, 120, 199, 573, 430, 111, 300, 700, 80, 50, 30, 40, 10, 22, 37, 77, 100, 240, 183, 143, 377, 133, 445, 345, 321, 111,12,3,34,456,235,214,43,21]
 30             }
 31         }
 32         var ctx = canvas.getContext('2d');
 33         // 绘制title
 34         drawText('单位: 次', config.Left, config.Top - 30, 'normal 22px Arial', '#a3a2a7');
 35         // 绘制网格线
 36         darwBackLine('#cccccc', config.yLine.splitcount, 1, config.yLine.data);
 37         // 绘制x轴
 38         drawXLine('#939099', config.xLine.splitcount, 2, config.xLine.data);
 39         // 绘制线条
 40         drawLines(config.color[0], 2,config.series.data);
 41         // 绘制图例
 42         drawItem('test', config.color[0], 2);
 43 
 44 
 45         function darwBackLine(color, splitcount, linewidth, data) {
 46             var len = Math.floor((config.height - config.Top - config.Bottom)/splitcount);
 47             var start = config.Top;
 48             for (var i = 0; i < splitcount; i++) {
 49                 var point = start+len*i;
 50                 drawLine(config.Left, point, (config.width/2 - config.Right)*scale, point, color, linewidth);
 51                 drawText(data[splitcount-i], 10, point, 'normal 22px Arial', '#605d68');
 52             }
 53             drawText(data[splitcount-i], 10, point+len, 'normal 22px Arial', '#605d68');
 54         }
 55 
 56         function drawXLine(color, splitcount, linewidth, data) {
 57             var left = config.Left;
 58             var top = config.height - config.Bottom;
 59             var right = (config.width/2 - config.Right)*scale;
 60             drawLine(config.Left, top, right, top, color, linewidth);
 61             var len = (right - left)/splitcount;
 62 
 63             for (var i = 0; i < splitcount+1; i++) {
 64                 var xpoint = left+len*i;
 65                 drawLine(xpoint,top+linewidth,xpoint, top-5*scale, color, linewidth);
 66                 var PanningLeft = data[i].toString().length*5;
 67                 drawText(data[i], xpoint-PanningLeft, top+15*scale, 'normal 22px Arial', '#605d68')
 68             }
 69         }
 70 
 71         function drawLines(color, linewidth, data) {
 72             var count = data.length;
 73             var left = config.Left;
 74             var top = config.height - config.Bottom;
 75             var right = (config.width/2 - config.Right)*scale;
 76             var len = (right - left)/(count - 1);
 77             var i = 0;
 78 
 79             var interval = setInterval(function() {
 80                 if(i >= count - 1){
 81                     clearInterval(interval);
 82                     return;
 83                 }
 84                 drawLine(left+len*i, top-(data[i]/800)*(top - config.Top), left+len*(i+1), top-(data[i+1]/800)*(top - config.Top), color, linewidth, 'bevel');
 85                 i++;
 86             }, 30);
 87         }
 88 
 89         function drawItem(text, color, linewidth) {
 90             var right = (config.width/2 - config.Right)*scale;
 91             var left = right-(text.length*10);
 92             drawText(text, left, config.Top - 10, 'normal 22px Arial', '#605d68');
 93             drawLine(left-20, config.Top - 15, left-80, config.Top - 15, color, linewidth);
 94         }
 95 
 96         function drawLine(startX, startY, endX, endY, color, width, lineJoin) {
 97             ctx.beginPath();
 98             ctx.moveTo(startX, startY);
 99             ctx.lineTo(endX, endY);
100             if(color){
101                 ctx.strokeStyle = color
102             }
103 
104             if(width){
105                 ctx.lineWidth = width*scale;
106             }
107 
108             if(lineJoin){
109                 ctx.lineJoin = lineJoin;
110             }
111             
112             ctx.closePath();
113             ctx.stroke(); 
114         }
115 
116         function drawText(text, x, y, font, color) {
117             ctx.font= font;
118             ctx.fillStyle= color;
119             ctx.fillText(text, x, y);
120         }
121     </script>
122 </body>
123 </html>

2.canvas成分暗许大小是300px*150px,大家设置宽高的时候,要求选拔canvas标签中的width和height属性,而不是css中的width和height属性

  <div class=”box”>
    <canvas id=”mycanvas” width=”700px”
height=”700px”></canvas>
  </div>

没错安装宽高写法是:

因为canvas放大了两倍,所以绘制时,参数都要放大两倍(比如半径),那样就到家的缓解了canvas图像模糊的难点

<canvas id=”canvas” width=”500″ height=”500″>

  您的浏览器不帮衬Canvas

</canvas>

谬误安装宽高写法是:

<canvas id=”canvas” style=”width: 500px;height: 500px;”>

4858美高梅,  您的浏览器不帮助Canvas

</canvas>

那里在行内样式和内联样式中安装canvas的width和height都以不当的,

那样做会让canvas的宽高被拉伸或减少,从而使得绘制的图片并不跟预想的同1。

 

若果如此说的不透彻的话,也可以这样精通:

诸如我们在生活中要选拔一块画布用来作画,当大家去市场上摘取画布的时候,发现画布的尺码大小有各式种种的,可是大家的画板大小是500*500的,所以大家需求选取1块500*500的画布,在此处大家须求采纳第二种写法:

<canvas id=”canvas” width=”500″ height=”500″>

  您的浏览器不辅助Canvas

</canvas>

来选择正确的契合画板尺寸的画布,因为那种写法正好是为了大家挑选画布的尺寸而规划的。

 

买回来画布后,大家供给绘制更大越来越宽的画,所以大家把原来的画板尺寸扩大了,然而我们又不想麻烦再跑市镇一趟去选取画布,那里如若大家事先买的画布是有弹性的,可以被拉伸并且能够健康使用。

那种情况下就能够利用css中的width和height属性设置画布的宽和高(行内样式和内联样式)来拉伸画布的高低,然而此间须要留意一点的是:我们是在画布默许尺寸大小300*150的根基方面拉伸的。不过透过拉伸后的画布在绘制图画的时候会跟预想的结果不太1致。

 

此处列举的例证是为着大家越来越好的敞亮那三种景况,至于为什么,浏览器依旧HTML5蓄意为那三种供给而设置的三种分歧的操作宽高的法子,大家记住可以了

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有