2016-12-22 3 views
0

Я хочу наложить фоновое изображение с помощью некоторого текста, в Fabric.js есть способ размыть фон, чтобы текст стал более читаемым?Как размыть фоновое изображение в Fabric.js

Я пробовал фильтр, но мог только изменить фоновое изображение в оттенки серого, размытие не оказало никакого эффекта.

Заранее спасибо.

ответ

0

Я создал эту суть, он добавляет стек размывания в качестве фильтра для класса ткани.

https://gist.github.com/human-a/25b7f58565b89de4e999ef2f4de1982c

/** 
* Stack blur filter for fabricjs 
* Example: 
* obj.filters.push(new fabric.Image.filters.StackBlur(6)); 
* obj.applyFilters(canvas.renderAll.bind(canvas)); 
* 
* Heavily inspired by: 
* https://gist.github.com/pierrickouw/2ab679159beee9d80ca6 
* http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html 
* uses stackBlurCanvasRGBA function but could be swapped be stackBlurCanvasRGB 
* @see: http://www.quasimondo.com/StackBlurForCanvas/StackBlur.js 
*/ 

(function() { 

    var fabric = window.fabric, 
    extend = fabric.util.object.extend; 

    var mul_table = [ 
    512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, 
    454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, 
    482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, 
    437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, 
    497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, 
    320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, 
    446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, 
    329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, 
    505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, 
    399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, 
    324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, 
    268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, 
    451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, 
    385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, 
    332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, 
    289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 
    ]; 
    var shg_table = [ 
    9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 
    17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 
    22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 
    22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 
    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
    23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 
    ]; 

    function BlurStack() { 
     this.r = 0; 
     this.g = 0; 
     this.b = 0; 
     this.a = 0; 
     this.next = null; 
    } 

    fabric.Image.filters.StackBlur = fabric.util.createClass(fabric.Image.filters.BaseFilter,{ 

     /** 
     * Filter type 
     */ 
     type: 'StackBlur', 

     /** 
     * Constructor 
     */ 
     initialize: function(radius) { //radius of the blur 
      this.radius = radius || 0; 
      if(this.radius > 180) { 
       this.radius = 180; 
      } 

      if(this.radius < 1) { 
       this.radius = 0; 
      } 
     }, 

     /** 
     * Applies blur to canvas element 
     */ 
     applyTo: function(canvas) { 
      // Don't apply blur if it's zero 
      if (!this.radius) return; 

      var radius = this.radius; 
      var width = canvas.width; 
      var height = canvas.height; 
      var context = canvas.getContext("2d"); 
      var imageData; 

      imageData = context.getImageData(0, 0, width, height); 

      var pixels = imageData.data; 

      var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, 
       r_out_sum, g_out_sum, b_out_sum, a_out_sum, 
       r_in_sum, g_in_sum, b_in_sum, a_in_sum, 
       pr, pg, pb, pa, rbs; 

      var div = radius + radius + 1; 
      var widthMinus1 = width - 1; 
      var heightMinus1 = height - 1; 
      var radiusPlus1 = radius + 1; 
      var sumFactor = radiusPlus1 * (radiusPlus1 + 1)/2; 

      var stackStart = new BlurStack(); 
      var stack = stackStart; 
      for (i = 1; i < div; i++) { 
       stack = stack.next = new BlurStack(); 
       if (i === radiusPlus1) var stackEnd = stack; 
      } 
      stack.next = stackStart; 
      var stackIn = null; 
      var stackOut = null; 

      yw = yi = 0; 

      var mul_sum = mul_table[radius]; 
      var shg_sum = shg_table[radius]; 

      for (y = 0; y < height; y++) { 
       r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; 

       r_out_sum = radiusPlus1 * (pr = pixels[yi]); 
       g_out_sum = radiusPlus1 * (pg = pixels[yi+1]); 
       b_out_sum = radiusPlus1 * (pb = pixels[yi+2]); 
       a_out_sum = radiusPlus1 * (pa = pixels[yi+3]); 

       r_sum += sumFactor * pr; 
       g_sum += sumFactor * pg; 
       b_sum += sumFactor * pb; 
       a_sum += sumFactor * pa; 

       stack = stackStart; 

       for(i = 0; i < radiusPlus1; i++) { 
        stack.r = pr; 
        stack.g = pg; 
        stack.b = pb; 
        stack.a = pa; 
        stack = stack.next; 
       } 

       for(i = 1; i < radiusPlus1; i++) { 
        p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); 
        r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i); 
        g_sum += (stack.g = (pg = pixels[p+1])) * rbs; 
        b_sum += (stack.b = (pb = pixels[p+2])) * rbs; 
        a_sum += (stack.a = (pa = pixels[p+3])) * rbs; 

        r_in_sum += pr; 
        g_in_sum += pg; 
        b_in_sum += pb; 
        a_in_sum += pa; 

        stack = stack.next; 
       } 


       stackIn = stackStart; 
       stackOut = stackEnd; 
       for (x = 0; x < width; x++) { 
        pixels[yi+3] = pa = (a_sum * mul_sum) >> shg_sum; 
        if (pa !== 0) 
        { 
         pa = 255/pa; 
         pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; 
         pixels[yi+1] = ((g_sum * mul_sum) >> shg_sum) * pa; 
         pixels[yi+2] = ((b_sum * mul_sum) >> shg_sum) * pa; 
        } else { 
         pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0; 
        } 

        r_sum -= r_out_sum; 
        g_sum -= g_out_sum; 
        b_sum -= b_out_sum; 
        a_sum -= a_out_sum; 

        r_out_sum -= stackIn.r; 
        g_out_sum -= stackIn.g; 
        b_out_sum -= stackIn.b; 
        a_out_sum -= stackIn.a; 

        // eslint-disable-next-line 
        p = (yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1)) << 2; 

        r_in_sum += (stackIn.r = pixels[p]); 
        g_in_sum += (stackIn.g = pixels[p+1]); 
        b_in_sum += (stackIn.b = pixels[p+2]); 
        a_in_sum += (stackIn.a = pixels[p+3]); 

        r_sum += r_in_sum; 
        g_sum += g_in_sum; 
        b_sum += b_in_sum; 
        a_sum += a_in_sum; 

        stackIn = stackIn.next; 

        r_out_sum += (pr = stackOut.r); 
        g_out_sum += (pg = stackOut.g); 
        b_out_sum += (pb = stackOut.b); 
        a_out_sum += (pa = stackOut.a); 

        r_in_sum -= pr; 
        g_in_sum -= pg; 
        b_in_sum -= pb; 
        a_in_sum -= pa; 

        stackOut = stackOut.next; 

        yi += 4; 
       } 
       yw += width; 
      } 


      for (x = 0; x < width; x++) { 
       g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; 

       yi = x << 2; 
       r_out_sum = radiusPlus1 * (pr = pixels[yi]); 
       g_out_sum = radiusPlus1 * (pg = pixels[yi+1]); 
       b_out_sum = radiusPlus1 * (pb = pixels[yi+2]); 
       a_out_sum = radiusPlus1 * (pa = pixels[yi+3]); 

       r_sum += sumFactor * pr; 
       g_sum += sumFactor * pg; 
       b_sum += sumFactor * pb; 
       a_sum += sumFactor * pa; 

       stack = stackStart; 

       for(i = 0; i < radiusPlus1; i++) 
       { 
        stack.r = pr; 
        stack.g = pg; 
        stack.b = pb; 
        stack.a = pa; 
        stack = stack.next; 
       } 

       yp = width; 

       for(i = 1; i <= radius; i++) 
       { 
        yi = (yp + x) << 2; 

        r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i); 
        g_sum += (stack.g = (pg = pixels[yi+1])) * rbs; 
        b_sum += (stack.b = (pb = pixels[yi+2])) * rbs; 
        a_sum += (stack.a = (pa = pixels[yi+3])) * rbs; 

        r_in_sum += pr; 
        g_in_sum += pg; 
        b_in_sum += pb; 
        a_in_sum += pa; 

        stack = stack.next; 

        if(i < heightMinus1) 
        { 
         yp += width; 
        } 
       } 

       yi = x; 
       stackIn = stackStart; 
       stackOut = stackEnd; 
       for (y = 0; y < height; y++) 
       { 
        p = yi << 2; 
        pixels[p+3] = pa = (a_sum * mul_sum) >> shg_sum; 
        if (pa > 0) 
        { 
         pa = 255/pa; 
         pixels[p] = ((r_sum * mul_sum) >> shg_sum) * pa; 
         pixels[p+1] = ((g_sum * mul_sum) >> shg_sum) * pa; 
         pixels[p+2] = ((b_sum * mul_sum) >> shg_sum) * pa; 
        } else { 
         pixels[p] = pixels[p+1] = pixels[p+2] = 0; 
        } 

        r_sum -= r_out_sum; 
        g_sum -= g_out_sum; 
        b_sum -= b_out_sum; 
        a_sum -= a_out_sum; 

        r_out_sum -= stackIn.r; 
        g_out_sum -= stackIn.g; 
        b_out_sum -= stackIn.b; 
        a_out_sum -= stackIn.a; 

        // eslint-disable-next-line 
        p = (x + (((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width)) << 2; 

        r_sum += (r_in_sum += (stackIn.r = pixels[p])); 
        g_sum += (g_in_sum += (stackIn.g = pixels[p+1])); 
        b_sum += (b_in_sum += (stackIn.b = pixels[p+2])); 
        a_sum += (a_in_sum += (stackIn.a = pixels[p+3])); 

        stackIn = stackIn.next; 

        r_out_sum += (pr = stackOut.r); 
        g_out_sum += (pg = stackOut.g); 
         b_out_sum += (pb = stackOut.b); 
         a_out_sum += (pa = stackOut.a); 

         r_in_sum -= pr; 
         g_in_sum -= pg; 
         b_in_sum -= pb; 
         a_in_sum -= pa; 

         stackOut = stackOut.next; 

         yi += width; 
        } 
       } 
      context.putImageData(imageData, 0, 0); 

     }, 

     /** 
     * Returns object representation of an instance 
     */ 
     toObject: function() { 
      return extend(this.callSuper('toObject'), { 
       radius: this.radius 
      }); 
     } 
    }); 

    fabric.Image.filters.StackBlur.fromObject = function(object) { 
     return new fabric.Image.filters.StackBlur(object); 
    }; 

})()