美文网首页
红包照片四不像(二)——canvas基础

红包照片四不像(二)——canvas基础

作者: 金小可 | 来源:发表于2016-09-19 19:50 被阅读32次

    在前面一篇文章中,我们通过css的方式实现了红包照片的模糊效果和偷窥镜。
    但是通过demo发现,效果并不是特别好,尤其是移动设备上的 动画性能实在无法接受。
    也可以通过canvas来实现相同的效果,本篇先来了解一下canvas的使用。

    一、canvas基础

    1、canvas本质

    a.标签;
    b.画布;
    

    2、基本使用

    var canvas = document.getElementById('canvas_id'); //获取canvas
    canvas.height = document.documentElement.clientWidth; //设置宽高
    canvas.width = document.documentElement.clientHeight;
    var context = canvas.getContext('2d'); //获取2d绘图context
    
    context.beginPath();  
      ...... //绘图路径
    context.closePath();
    
    context.fillStyle = ‘red'; //填充样式,描边样式使用strokeStyle
    context.fill(); // 填充绘图,描边绘图使用stroke()
    

    3、基础API(路径)

    context.moveTo(x,y) // 确定起点
    context.lineTo(x,y) // 绘制线段
    context.fillRect(x,y,width,height) // 填充矩形
    context.strokeRect(x,y,width,height) // 描边矩形
    // 绘制圆弧,参数包含圆心坐标/半径/起止弧度点/弧度行进方向
    context.arc(x, y, radius, starAngle,endAngle, anticlockwise)
    
    context.clearRect(x,y,width,height) //清除画布某矩形区域
    
    // 贝塞尔曲线
    context.quadraticCurveTo(qcpx,qcpy,qx,qy)
    context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) 
    
    // 渐变,起始点以及偏移点点颜色
    var lGradient = context.createLinearGradient(xStart,yStart,xEnd,yEnd) // 线性
    var rGradient = context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd) // 径向
    *Gradient.addColorStop(offset,color)
    
    context.translate(x,y) // 平移
    context.scale(x,y) // 缩放
    context.rotate(angle) // 旋转
    // 备注:以上三个变化操作的不是绘图,而是坐标轴
    
    context.globalCompositeOperation=type //图形组合
    /*    type:
            source-over(默认值):在原有图形上绘制新图形
            destination-over:在原有图形下绘制新图形
            source-in:显示原有图形和新图形的交集,新图形在上,所以颜色为新图形的颜色
            destination-in:显示原有图形和新图形的交集,原有图形在上,所以颜色为原有图形的颜色
            source-out:只显示新图形非交集部分
            destination-out:只显示原有图形非交集部分
            source-atop:显示原有图形和交集部分,新图形在上,所以交集部分的颜色为新图形的颜色
            destination-atop:显示新图形和交集部分,新图形在下,所以交集部分的颜色为原有图形的颜色
            lighter:原有图形和新图形都显示,交集部分做颜色叠加
            xor:重叠部分不显示
            copy:只显示新图形
    */
    
    // 阴影
    context.shadowOffsetX = 10;
    context.shadowOffsetY = 10;
    context.shadowColor = 'rgba(100,100,100,0.5)';
    context.shadowBlur = 1.5;
    
    // 绘制文字
    context.fillText(text,x,y)  
    context.strokeText(text,x,y)
    
    // 画笔画布状态暂存
    context.save()
    context.restore()
    
    context.drawImage // 绘图——下面单独介绍
    

    二、绘图api相关

    1、api介绍

    context.drawImage(image, x, y, w, h) // Image对象、起始坐标、绘制宽高(可省略)
    
    context.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)// 将Image的sx、sy位置sw、sh大小的图像绘制再画布dx、dy位置dw、dh大小的地方
    
    context.fillStyle = context.createPattern(image,type)
    /*  type:   no-repeat:不平铺
              repeat-x:横方向平铺
              repeat-y:纵方向平铺
              repeat:全方向平铺   */
    
    context.clip() // 设置绘制的封闭区域
    
    // imagedata中每4个元素代表一个像素的rgba数据,对应图像从左到右从上到下的像素
    var imagedata=context.getImageData(sx,sy,sw,sh)
    context.putImageData(imagedata,dx,dy,dirtyX,dirtyY,dirtyWidth,dirtyHeight) 
    

    2、上帝绘图模式

    由于可以获取到图片每个像素的数据,包括rgba,可以通过改变任何像素的值为任何值来达到预期的效果。(just like the God)
    那么我们究竟可以做些什么呢?
    一般情况下,可以通过像素色彩的计算实现PS中一些比较简单的滤镜效果,例如灰度图片只需要对单个像素的rgb值做加权平均就可以了,红色图片只需要把每个像素的r值设置为255即可。
    下面详细介绍几种简单的算法。

    三、滤镜算法

    1、灰度

    // 一般采用加权平均值,权值可以任意选取,常用 0.3、0.59、0.11;
    r = g = b = r * rWeight + g * gWeight + b * bWeight; 
    // 也可以使用其他的一些技巧,例如MAX
    r = g = b = Math.max(r, g, b); 
    

    2、灰度加强

    r =(2*g - b + r)* r / 255;
    g =(2*b - g + r)* r / 255;
    b =(2*b - g + r)* g / 255;
    ... //再做灰度处理
    

    3、反色——底片效果

    r = 255 - r;
    g = 255 - g;
    b = 255 - b;
    

    4、黑白

    var temp = r * rWeight + g * gWeight + b * bWeight; // 可以采用灰度中的多种方式
    r = g = b = temp > 128 ? 255 : 0; // 这里的取值也可以灵活处理,达到不同的黑白灰的效果
    

    5、斑驳

    r = r > 128 ? 255 : 0;
    g = g > 128 ? 255 : 0;
    b = b > 128 ? 255 : 0;
    

    6、怀旧

    r = r * 0.393 + g * 0.769 + b * 0.189; 
    g = r * 0.349 + g * 0.686 + b * 0.168; 
    b = r * 0.272 + g * 0.534 + b * 0.131; 
    

    7、色彩通道——纯色通道

    // 纯色比较简单,包括一些单色通道和混合通道
    r = 255; // 红色
    r= g = 255; // 黄色(红+绿)
    r = 0;// 反红色,有别于(绿+蓝)
    // 这种方式比较灵活,可以通过调整rgb为任意常数值,来实现一些特别的效果
    

    8、锐化

    // rgb的值均加上当前位置的颜色值与四面八方颜色值的差为当前值
    function getColor(color) {
          color[i][j] *= 10;
          for (var row = -1; row < 2; row++) {
                for (var col = -1; col < 2; col++) {
                      color[i][j] -= color[i + row][j + col];
                }
          }
    }
    

    9、马赛克

    // 某个方块中所有像素的值取同一个位置的值
    for (var i=0; i< Height; i++) {
        for (var j=0; j<Width; j++) {
            var iTemp = i - i % RADUIS;
            var jTemp = j - j % RADUIS;
            r[i * Width + j] =  r[iTemp * Width + jTemp];
            g[i * Width + j] =  g[iTemp * Width + jTemp];
            b[i * Width + j] =  b[iTemp * Width + jTemp];
       }
    }
    

    10、模糊

    // 每个像素的值均取周围像素值的平均值
    for (var i=0; i< Height; i++) {
        for (var j=0; j<Width; j++) {
            color[i * Width + j] =  getColor(i, j);
       }
    }
    function getColor(i, j) {
        var result = 0, count = 0;
        for (var m = i - RADUIS;m < i + RADUIS; m++) {
              if (m < 0) {               continue;        }
              for(var n = j - RADUIS; n < j + RADUIS; n++) {
                  if (n < 0) {            continue;        }
                  result += data[m * width + n];
                  count++;
              }
          }
          return result/count;
    }
    

    11、浮雕

    // 相邻点的差值做类似半灰度的处理
    for (var i=0; i< Height; i++) {
        for (var j=0;j<Width;j++) {        
            r[i* Width + j] = r[(i* Width + j) + 1] - r[i* Width + j] + 128;
            g[i* Width + j] = g[(i* Width + j) + 1] - g[i* Width + j] +128;
            b[i* Width + j] = b[(i* Width + j) + 1] - b[i* Width + j] +128;
            ... //再做灰度处理(可能会有一些彩色的线条,可以通过灰度处理去掉)
         }
    }
    

    四、滤镜示例

    Just Load:http://tkixp9.github.io/redbag/draw_image_as_god.html

    五、canvas实现红包照片

    TO BE CONTINUED...

    相关文章

      网友评论

          本文标题:红包照片四不像(二)——canvas基础

          本文链接:https://www.haomeiwen.com/subject/keudsttx.html