Contents
  1. 1. 图片四周trim处理

图片四周trim处理

@(博客)[canvas, 透明, transparent, trim, 图片, image]

  • 最近在用canvas写一些生成类的模板,说白了就是用canvas画画,画了之后生成一张图片。
  • 策划有这么一个需求:用户上传一张二维码,就自动变成一张非有效区域变成透明的二维码。也就是要把非黑色的部分变成透明。如图
  • QRCode01.png
  • 说一下思路:
  1. 我们知道canvas有个方法: getImageData,这个方法返回的是一个数组,记录着每个像素点的rgba值。所以可以这让认为:这是一个每4个为一组的数组。
  2. rgba每一个值都是在0-255之间,那就很简单了,只要判断rgb三个值,如果都小于10,就让为这个像素点是黑色的。当然,这个临界值不一定是10,具体的话看看自己想达到怎么样的效果。
  • 思路说完,看看代码吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    TicketObj.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;
    };
  • 好了,已经满足策划的需求了。如图:

  • QRCode01.png
  • 但是,原来的二维码四周可能会有白边。这会导致透明出来的二维码的大小可能不一样,那么,我们需要进一步把二维码四个边的透明区域去掉。
  • 还是老方法,用canvasgetImageData
  • 直接上代码吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    TicketObj.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;
    };
  • 那这份代码其实是来自githubRemy兄弟的trim-canvas.js

  • 最后,我们导出image之前,只要调用一下这个函数就行了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    TicketObj.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); //就在这里做了图片的trim
    var image = new Image();
    image.src = canvas.toDataURL('imgage/png');
    return image;
    };
  • 效果如图:

  • QRCode03.png
  • 参考:
    强子的博文:http://www.cnblogs.com/jelly7723/p/5576442.html
    Remy:https://gist.github.com/remy/784508
Contents
  1. 1. 图片四周trim处理