1. 程式人生 > >canvas 踩坑記錄

canvas 踩坑記錄

adr set base64 composite 瀏覽器 圖片 IT log UNC

一、繪制一個帶有多張圖片和文字的canvas。要求將一張矩形的圖片,放置進去顯示為圓角矩形的圖片

  解決方案,先把圖片處理成圓角矩形的樣子,再放進去就可以了

  繪制圓角矩形圖片的解決方案

<img src="http://pics.sc.chinaz.com/files/pic/pic9/201505/apic11973.jpg" width="400" />
<!--canvas的默認畫布大小為300×150-->
<canvas id="j-tab4-canvas" style="border: 1px solid red;">  
		當前瀏覽器不支持canvas,請更換瀏覽器後再試
</canvas>
<script>
	window.onload = function() {
		var canvas = document.getElementById("j-tab4-canvas");
		canvas.width = 400;
		canvas.height = 400;
		var context = canvas.getContext("2d");

		//繪制圓角矩形
		context.roundRect(0, 0, 400, 400, 30, true);

		var img = new Image();
				
		img.src = "img/dog.jpg";
		img.onload = function() {
			context.globalCompositeOperation = ‘source-in‘;
			context.drawImage(img, 0, 0, canvas.width, canvas.height);
			//最後輸出一張base64格式的圖片url,成功生成一張圓角矩形的圖片
			console.log(canvas.toDataURL(‘image/jpeg‘,0.92))    
					
		}
	}

	//圓角矩形
	CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height, radius, fill, stroke) {
		if(typeof stroke == "undefined") {
			stroke = true;
		}
		if(typeof radius === "undefined") {
			radius = 5;
		}
		this.beginPath();
		this.moveTo(x + radius, y);
		this.lineTo(x + width - radius, y);
		this.quadraticCurveTo(x + width, y, x + width, y + radius);
		this.lineTo(x + width, y + height - radius);
		this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
		this.lineTo(x + radius, y + height);
		this.quadraticCurveTo(x, y + height, x, y + height - radius);
		this.lineTo(x, y + radius);
		this.quadraticCurveTo(x, y, x + radius, y);
		this.closePath();

		if(stroke) {
			//線條顏色
			this.strokeStyle = "rgba(0,0,0,0)";
			this.stroke();
		}
		if(fill) {
			//填充顏色
			this.fillStyle = "rgba(0,0,0,1)";
			this.fill();
		}
	};
</script>

  效果如下圖

技術分享圖片

踩坑說明 :

1、在行間使用style="width:300px;height:200px",是無效的。強烈建議用js來設置canvas的寬高

1、繪制圖片的 drawImage()方法。在把圖片繪制的時候,自帶了圖片壓縮功能。繪制圖片的時候盡量使用質量高一點的圖片(上傳一張5M的圖片,最後輸出300k)。不然容易出現圖片模糊的現象。另外就是無法控制壓縮的程度

2、canvas生成圖片的方法toDataURL(‘image/jpeg‘,0.92),帶有2個參數。這個方法在生成圖片的時候,也是自帶圖片壓縮功能

  這兩個值是參數的默認值。參數一是設置生成圖片的格式,可以是png,jpg。參數二,是設置壓縮圖片的程度,範圍是0-1,1為不壓縮,越靠近0,壓縮的越厲害

3、toDataURL()有跨域問題。

  假如繪制的圖片跨域了,就會提示 "Uncaught SecurityError: Failed to execute ‘toDataURL‘ on ‘HTMLCanvasElement‘: Tainted canvases may not be exported."(被汙染的畫布無法輸出)

  解決辦法:訪問的服務器允許,資源跨域使用,也就是說設置了CORS跨域配置,Access-Control-Allow-Origin(啟用了 CORS 的圖片

  繪制圖片如下所示:設置img.src要放下onload()的後面 

var img = new Image();
//訪問的服務器允許,資源跨域使用,也就是說設置了CORS跨域配置,Access-Control-Allow-Origin
img.setAttribute(‘crossOrigin‘, ‘anonymous‘);
img.onload = function() { context.globalCompositeOperation = ‘source-in‘; context.drawImage(img, 0, 0, canvas.width, canvas.height); //最後輸出一張base64格式的圖片url,成功生成一張圓角矩形的圖片 console.log(canvas.toDataURL(‘image/jpeg‘,0.92)) } img.src="http://pics.sc.chinaz.com/files/pic/pic9/201505/apic11973.jpg"

  4、canvas繪圖模糊的問題

    解決辦法原理,將canvas畫布放大來繪畫,再縮小顯示。詳情請參考以下兩篇博文

    https://segmentfault.com/a/1190000003730246,

    https://www.jianshu.com/p/4c4312dc7fc5

    這裏粗略講一下我的解決過程。我創建一個canvas畫布,畫了一個圓和寫了一句話,可以看到圓和字線條上都是有點模糊的

  技術分享圖片技術分享圖片

  

canvas 踩坑記錄