图片四周trim处理
Contents
图片四周trim处理
@(博客)[canvas, 透明, transparent, trim, 图片, image]
- 最近在用
canvas
写一些生成类的模板,说白了就是用canvas
画画,画了之后生成一张图片。 - 策划有这么一个需求:用户上传一张二维码,就自动变成一张非有效区域变成透明的二维码。也就是要把非黑色的部分变成透明。如图
- 说一下思路:
- 我们知道
canvas
有个方法:getImageData
,这个方法返回的是一个数组,记录着每个像素点的rgba
值。所以可以这让认为:这是一个每4个为一组的数组。 rgba
每一个值都是在0-255之间,那就很简单了,只要判断rgb三个值,如果都小于10,就让为这个像素点是黑色的。当然,这个临界值不一定是10,具体的话看看自己想达到怎么样的效果。
思路说完,看看代码吧。
1234567891011121314151617181920TicketObj.prototype.transparentQRCode = function(imgObj) {var canvas = document.createElement('canvas');canvas.width = 300;canvas.height = 300;var ctx = canvas.getContext('2d');ctx.drawImage(imgObj, 0, 0, canvas.width, canvas.height);var img = ctx.getImageData(0, 0, canvas.width, canvas.height);var data = img.data;for(var i = 0, len = data.length; i < len; i += 4) {if(data[i] < 20 && data[i+1] < 20 && data[i+2] < 20) {continue;} else {data[i+3] = 0;}}ctx.putImageData(img, 0, 0);var image = new Image();image.src = canvas.toDataURL('imgage/png');return image;};好了,已经满足策划的需求了。如图:
- 但是,原来的二维码四周可能会有白边。这会导致透明出来的二维码的大小可能不一样,那么,我们需要进一步把二维码四个边的透明区域去掉。
- 还是老方法,用
canvas
的getImageData
。 直接上代码吧。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354TicketObj.prototype.trimImage = function(c){var ctx = c.getContext('2d'),copy = document.createElement('canvas').getContext('2d'),pixels = ctx.getImageData(0, 0, c.width, c.height),l = pixels.data.length,i,bound = {top: null,left: null,right: null,bottom: null},x, y;for (i = 0; i < l; i += 4) {if (pixels.data[i+3] !== 0) { //如果不透明x = (i / 4) % c.width;y = ~~((i / 4) / c.width);if (bound.top === null) {bound.top = y;}if (bound.left === null) {bound.left = x;} else if (x < bound.left) {bound.left = x;}if (bound.right === null) {bound.right = x;} else if (bound.right < x) {bound.right = x;}if (bound.bottom === null) {bound.bottom = y;} else if (bound.bottom < y) {bound.bottom = y;}}}var trimHeight = bound.bottom - bound.top,trimWidth = bound.right - bound.left,trimmed = ctx.getImageData(bound.left, bound.top, trimWidth, trimHeight);copy.canvas.width = trimWidth;copy.canvas.height = trimHeight;copy.putImageData(trimmed, 0, 0);// open new window with trimmed image:return copy.canvas;};那这份代码其实是来自
github
的Remy
兄弟的trim-canvas.js。最后,我们导出
image
之前,只要调用一下这个函数就行了。1234567891011121314151617181920212223242526TicketObj.prototype.transparentQRCode = function(imgObj) {// var canvas = document.getElementById('qrcode-canvas');var canvas = document.createElement('canvas');canvas.width = 300;canvas.height = 300;var ctx = canvas.getContext('2d');ctx.drawImage(imgObj, 0, 0, canvas.width, canvas.height);var img = ctx.getImageData(0, 0, canvas.width, canvas.height);var data = img.data;for(var i = 0, len = data.length; i < len; i += 4) {if(data[i] < 20 && data[i+1] < 20 && data[i+2] < 20) {continue;} else {data[i+3] = 0;}}ctx.putImageData(img, 0, 0);canvas = this.trimImage(canvas); //就在这里做了图片的trimvar image = new Image();image.src = canvas.toDataURL('imgage/png');return image;};效果如图:
- 参考:
强子的博文:http://www.cnblogs.com/jelly7723/p/5576442.html
Remy:https://gist.github.com/remy/784508