Boky
Boky

Reputation: 12084

Blur part of the image with Javascript/Jquery

I'm trying to blur a part of the photo. My code is as follows:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var rect = {};
var drag = false;
var imageObj = null;

function init() {
    imageObj = new Image();
    imageObj.onload = function () { ctx.drawImage(imageObj, 0, 0); };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);
}

function mouseDown(e) {
    rect.startX = e.pageX - this.offsetLeft;
    rect.startY = e.pageY - this.offsetTop;
    drag = true;
}

function mouseUp() { drag = false; }

function mouseMove(e) {
    if (drag) {
        ctx.clearRect(0, 0, 500, 500);
        ctx.drawImage(imageObj, 0, 0);
        rect.w = (e.pageX - this.offsetLeft) - rect.startX;
        rect.h = (e.pageY - this.offsetTop) - rect.startY;
        ctx.strokeStyle = 'blue';
        ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
        ctx.filter = 'blur(5px)';

    }
}
//
init();
<canvas id="canvas" width="500" height="500"></canvas>

I draw a rectangle but I want to apply the blur filter only on that rectangle not to the whole image as it is now. Any idea how to do that?

Here is the fiddle

Upvotes: 5

Views: 4770

Answers (3)

Debashis Chowdhury
Debashis Chowdhury

Reputation: 624

we can use fabric.js library. Here you can draw a rectangle and move it and resize it. The original fiddle was having some console error and scaling was not working. I have resolved them all in the bellow jsfiddle.

Here we first copy the original image and create a copy canvas and make the full image blur. Then on move or scaling of the rectangle just showing actual crop to show the proper blur section. enter image description here

function blurSelection(left=0, top=0, img=null) {
  if (img) {
    img.cropX = left;
    img.cropY = top;
    fabricCanvas.renderAll();
  } else {
    const image = fabric.Image.fromURL(blurredCanvas.toDataURL(), function (img) {
      img.cropX = left;
      img.cropY = top;
      img.width = 200; // Default
      img.height = 100; // Default
      img.objectCaching = false;
      fabricCanvas.add(img);
      img.bringToFront();
      img.on('moving', function (options) {
        const newLeft = options.target.left;
        const newTop = options.target.top;
        blurSelection(newLeft, newTop, img=options.target);
      });

      img.on('scaling', function (options) {
        const newLeft = options.target.left;
        const newTop = options.target.top;
        const newWidth = options.target.width * options.target.scaleX;
        const newHeight = options.target.height *  options.target.scaleY;
                    //console.log("scaleX",options.target.scaleX,'scaleY',options.target.scaleX,"newWidth",newWidth,"newHeight",newHeight)
        options.target.scaleX=1;
        options.target.scaleY=1;
        options.target.width=newWidth;
        options.target.height=newHeight;
      })
    });
  }
}

function copyCanvas() {
  const objects = fabricCanvas.getObjects();
  const copiedCanvas = fabricCanvas.toCanvasElement();

  const blurredImage = new fabric.Image(copiedCanvas);

  const filter = new fabric.Image.filters.Blur({
    blur: 0.8
  });
  blurredImage.filters.push(filter);
  blurredImage.applyFilters();

  blurredCanvas = new fabric.Canvas(copiedCanvas);
  window.blurredCanvas = blurredCanvas;
  blurredCanvas.add(blurredImage);
  blurredCanvas.renderAll();

  // Just for the inspection of the blurred image
  document.getElementById('asd').src = copiedCanvas.toDataURL();
}

https://jsfiddle.net/debchy/ajbpefk4/7/

Upvotes: 1

Deepu Reghunath
Deepu Reghunath

Reputation: 9713

working jsfiddle: https://jsfiddle.net/zoh5o9p5/

If you use a base64 image and do some changes it will work as you expected

made some changes in mouseMove function.

function mouseMove(e) {
    if (drag) {

        ctx.filter = 'blur(5px)';
        ctx.drawImage(imageObj, 0, 0);
        rect.w = (e.pageX - this.offsetLeft) - rect.startX;
        rect.h = (e.pageY - this.offsetTop) - rect.startY;
        ctx.strokeStyle = 'blue';

        if(rect.w>0 && rect.h>0)
        {
            imgDrow=ctx.getImageData(rect.startX, rect.startY, rect.w, rect.h);
        }
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.filter = 'none';
        ctx.drawImage(imageObj, 0, 0);

        w=rect.w<0?rect.startX+rect.w:rect.startX; 
        h=rect.h<0?rect.startY+rect.h:rect.startY;
        if(imgDrow)
        {
            ctx.putImageData(imgDrow,w, h);
        }
        ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);

    }

working jsfiddle: https://jsfiddle.net/zoh5o9p5/

Upvotes: 1

user9167318
user9167318

Reputation:

It is possible by using HTML5 Canvas

I have made a fiddle to blur the part 350 from image.
Fiddle Link: https://jsfiddle.net/k6aaqdx6/3/

Edit:

updated according to your fiddle: https://jsfiddle.net/tbjLk6eu/2

Code that I added:

imgData=ctx.getImageData(rect.startX, rect.startY, rect.w, rect.h);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.filter = 'none';
ctx.drawImage(imageObj, 0, 0);
ctx.putImageData(imgData,rw, rh);
ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);

Upvotes: 1

Related Questions