簡體   English   中英

所需的畫布模糊工具

[英]Needed canvas blurring tool

我有一個類似fabric.js( http://fabricjs.com/freedrawing/ )的繪圖應用程序
我想嵌入像Photoshop這樣的模糊工具( http://www.demowolf.com/tutorials/demo.php?id=1503&series=85&format=html

在此處輸入圖片說明

這是我的模糊功能,但是當我嘗試更改顏色時它不能正常工作,這是錯誤的,您可以在下面看到屏幕截圖...

function boxBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations ){
 if ( isNaN(radius) || radius < 1 ) return;

 radius |= 0;

 if ( isNaN(iterations) ) iterations = 1;
 iterations |= 0;
 if ( iterations > 3 ) iterations = 3;
 if ( iterations < 1 ) iterations = 1;

 var canvas  = document.getElementById( 'paper' );
 var context = canvas.getContext("2d");
 var imageData;

 try {
   try {
  imageData = context.getImageData( top_x, top_y, width, height );
   } catch(e) {

  // NOTE: this part is supposedly only needed if you want to work with local files
  // so it might be okay to remove the whole try/catch block and just use
  // imageData = context.getImageData( top_x, top_y, width, height );
  try {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
   imageData = context.getImageData( top_x, top_y, width, height );
  } catch(e) {
   alert("Cannot access local image");
   throw new Error("unable to access local image data: " + e);
   return;
  }
   }
 } catch(e) {
   alert("Cannot access image");
   throw new Error("unable to access image data: " + e);
   return;
 }

 var pixels = imageData.data;

 var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx,pa;  
 var wm = width - 1;
   var hm = height - 1;
    var wh = width * height;
 var rad1 = radius + 1;

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

 var r = [];
    var g = [];
    var b = [];
 var a = [];

 var vmin = [];
 var vmax = [];

 while ( iterations-- > 0 ){
  yw = yi = 0;

  for ( y=0; y < height; y++ ){
   rsum = pixels[yw]   * rad1;
   gsum = pixels[yw+1] * rad1;
   bsum = pixels[yw+2] * rad1;
   asum = pixels[yw+3] * rad1;


   for( i = 1; i <= radius; i++ ){
    p = yw + (((i > wm ? wm : i )) << 2 );
    rsum += pixels[p++];
    gsum += pixels[p++];
    bsum += pixels[p++];
    asum += pixels[p]
   }

   for ( x = 0; x < width; x++ ) {
    r[yi] = rsum;
    g[yi] = gsum;
    b[yi] = bsum;
    a[yi] = asum;

    if( y==0) {
     vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
     vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
    } 

    p1 = yw + vmin[x];
    p2 = yw + vmax[x];

    rsum += pixels[p1++] - pixels[p2++];
    gsum += pixels[p1++] - pixels[p2++];
    bsum += pixels[p1++] - pixels[p2++];
    asum += pixels[p1]   - pixels[p2];

    yi++;
   }
   yw += ( width << 2 );
  }

  for ( x = 0; x < width; x++ ) {
   yp = x;
   rsum = r[yp] * rad1;
   gsum = g[yp] * rad1;
   bsum = b[yp] * rad1;
   asum = a[yp] * rad1;

   for( i = 1; i <= radius; i++ ) {
     yp += ( i > hm ? 0 : width );
     rsum += r[yp];
     gsum += g[yp];
     bsum += b[yp];
     asum += a[yp];
   }

   yi = x << 2;
   for ( y = 0; y < height; y++) {

    pixels[yi+3] = pa = (asum * mul_sum) >>> shg_sum;
    if ( pa > 0 )
    {
     pa = 255 / pa;
     pixels[yi]   = ((rsum * mul_sum) >>> shg_sum) * pa;
     pixels[yi+1] = ((gsum * mul_sum) >>> shg_sum) * pa;
     pixels[yi+2] = ((bsum * mul_sum) >>> shg_sum) * pa;
    } else {
     pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0;
    }    
    if( x == 0 ) {
     vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
     vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
    } 

    p1 = x + vmin[y];
    p2 = x + vmax[y];

    rsum += r[p1] - r[p2];
    gsum += g[p1] - g[p2];
    bsum += b[p1] - b[p2];
    asum += a[p1] - a[p2];

    yi += width << 2;
   }
  }
 }
 context.globalAlpha = 0.8;
 context.putImageData( imageData, top_x, top_y );

}

在此處輸入圖片說明 誰能給我一些代碼示例?

有趣的問題!

以下是使用以下方法實現模糊畫筆的方法:

  • 屏幕外的畫布
  • 模糊效果算法
  • 合成以“剪切”圖像以適合用戶的筆觸
  • 將“模糊的筆觸”圖像后面的清晰圖像“拖到后面”。

演示: http : //jsfiddle.net/m1erickson/baDLp/

  1. 創建一個屏幕外畫布
  2. 讓用戶用刷子在屏幕上的畫布上繪畫
  3. 同時在屏幕外的畫布上繪制相同的筆觸
  4. 用戶刷完后...
  5. 將屏幕外畫布合成設置為“源入”(任何新圖形僅在現有筆觸上進行。
  6. drawImage屏幕外畫布上的圖像(僅在筆觸上繪制圖像)
  7. 使用模糊算法模糊屏幕外畫布(此時,屏幕外畫布僅在筆觸上包含模糊圖像)
  8. 清除屏幕上的畫布
  9. 使用drawImage將模糊的筆刷圖像從屏幕外的畫布復制到屏幕上的畫布。
  10. 將屏幕上的畫布合成設置為“目標結束”(在現有的模糊畫筆圖像后面繪制新圖形
  11. drawImage源圖像到屏幕畫布上(模糊的筆刷圖像仍然保留,並且源圖像繪制在該筆刷圖像的后面)

這就是代碼中的樣子:

(模糊效果是使用quasimondo的漂亮模糊算法完成的: http : //jsfiddle.net/m1erickson/baDLp/

// At this point, the temp canvas contains 
// only the users brush strokes

// draw the image "clipped" into those brush strokes
// using compositing == "source-in"

tempCtx.save();
tempCtx.globalCompositeOperation="source-in";
tempCtx.drawImage(img,0,0);
tempCtx.restore();

// blur the brush-image on the temp canvas

boxBlurCanvasRGBA("tempCanvas",0,0,tempCanvas.width,tempCanvas.height,4,0);


// clear the onscreen canvas

ctx.save();
ctx.clearRect(0,0,canvas.width,canvas.height);

// draw the brush-image from the temp canvas to the onscreen canvas
ctx.drawImage(tempCanvas,0,0);

// use compositing == "destination-over"
// to draw the source image *behind* the blurred brush-image

ctx.globalCompositeOperation="destination-over";
ctx.drawImage(img,0,0);
ctx.restore();

源圖像:

在此處輸入圖片說明

僅在描邊區域上繪制圖像然后模糊后,屏幕外畫布:

在此處輸入圖片說明

屏幕上帶有模糊區域的畫布合並到源圖像中:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM