Fabric.js: Server-Side Cropping

Created on 8 Jan 2014  路  12Comments  路  Source: fabricjs/fabric.js

I'm working on an ugly hack for a project that uses Fabric, but it's probably something others will want (and I can't share my code for this, since it's for my employer):

Specify a "crop area" (like drawing a rectangle), only instead of filling the inside you fill the area outside of the rectangle with rgba(0,0,0, 0.5). Users in my implementation draw the rectangle (using mouse events), then can resize it as they please.

When you call toJSON(), it passes this as a "crop area" to the server-side API, which reduces the image. (I do this on the server side since I dynamically resize the canvas based on the viewport, and will store the proportions so we can crop the full-size image).

When you restore from JSON (in my implementation, the original picture is restored), you also redraw the "crop area" if specified.

needs_confirmation

Most helpful comment

I do exactly this in my app.

The way I do it is as follows:

  1. Overlay the Fabric canvas over the top of the actual image that you wish to crop
  2. Set the backgroundColor of the Fabric canvas to rgba(0,0,0,0.5)
  3. set the rectangle objects background as 'transparent'
  4. in the 'after:render' event, perform a clearRect call to the fabric context in order to cut out the rectangle after each render is performed, thus allowing the image below to show through.

This works perfectly. Here is an image to show you how it looks in my app:

example

As you can see i've made a few extra modifications to the fabric source to give me rounded control handles as well as cropping gridlines but the main premise is the same.

EDIT : Sorry, I've just realised that that is exactly what you are doing. I'm a little bit confused as to what it is you are asking? Are you requesting that this is added as a feature of Fabric itself?

All 12 comments

So... I'm trying to understand the exact feature here.

What's drawn in the middle area? What color is it? Canvas background? If we're talking about canvas-level cropping, we already have support for it via canvas.clipTo = function(){ ... }

The area outside the rectangle is darkened. The area inside is left unchanged.

My implementation was drawing/redrawing a black rectangle to a canvas over the fabric canvas (using Javascript), then clearing the rectangle for the area of an active Fabric object. (The non-fabric Canvas has an opacity less than 1.0.) Then when the user presses "Save", it just passes [x1, y1, x2, y2] for the cropping rectangle separately from the JSON encoded canvas.

(Client-side cropping is, in my use case, absolutely undesirable. Users need to be able to come back in the future, load the original image, and readjust the cropping down the road.)

The exact procedure is as follows:

  1. Draw a rectangle with no fill or border. Set it to the active element.
  2. When a user resizes the active rectangle, re-render the overlay canvas.
  3. When the active element is in any way unselected, delete it and save the dimensions of the cropping overlay

It's a bit hacky, but it works for me. If you feel like streamlining this for a general purpose "I will crop this in PHP, don't do it here" type feature, that'd be pretty cool. If not, feel free to close this issue. :)

I do exactly this in my app.

The way I do it is as follows:

  1. Overlay the Fabric canvas over the top of the actual image that you wish to crop
  2. Set the backgroundColor of the Fabric canvas to rgba(0,0,0,0.5)
  3. set the rectangle objects background as 'transparent'
  4. in the 'after:render' event, perform a clearRect call to the fabric context in order to cut out the rectangle after each render is performed, thus allowing the image below to show through.

This works perfectly. Here is an image to show you how it looks in my app:

example

As you can see i've made a few extra modifications to the fabric source to give me rounded control handles as well as cropping gridlines but the main premise is the same.

EDIT : Sorry, I've just realised that that is exactly what you are doing. I'm a little bit confused as to what it is you are asking? Are you requesting that this is added as a feature of Fabric itself?

It's there a better way to implement this in fabric js 1.7.17 or 2.0 (beta) ?

also is there any example ( jsfiddle / jsbin /codepen ) of this? ^^

to crop an image in fabricjs version 2, you can specify cropx and cropy, and width and height of box. the image will be cropped then.

there is no dragging interface.

thanks, I know how to crop the image, what I want to achieve is the interface:

  • fabric background image
  • Overlay dark rect rgba(0, 0, 0, 0.5)
  • Crop area: rect transparent ( drag / edit )

you need to use fabric events, reverting the scale factor from the scaling event, and modify the cropx, cropy, width, height inside the scaling event manager. then you need some check to do not go out of bounds.

Ok, thanks asturur, one last question:
crop-area
( Left: how it should look ^^, Right: can't see trough dark-rect
I tried to use globalCompositionOperation / clearRect() to cut the crop-rect, but I need to see the fabric backgroundImage, is there any way to achieve this?

My opinion is that you should extend the default image class, create a croppableImage and use that.

In the render function, draw the full image, draw over it a semi transparent dark rect, then draw on top of it the cropped image. That will make the trick.

Ok thanks, I'll try that ^^

Hi @GordoRank, is there any available source code for your cropper application? I love the look of your cropping tool.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhangzhzh picture zhangzhzh  路  4Comments

semiadam picture semiadam  路  3Comments

bhaskardas9475 picture bhaskardas9475  路  4Comments

eddieyangtx picture eddieyangtx  路  5Comments

semiadam picture semiadam  路  3Comments