views:

390

answers:

3

I want to crop a rectangular image to a non-rectangular shape. I realize that if you take that completely literally, it's not possible. What I want to end up with is image X, cropped to shape Y, on a transparent background.

Let's say for example that I want to take a picture of the Idaho flag and crop it to the shape of the state of Idaho. I imagine I would do something like this:

  1. Create an image that has opaque pixels for the shape of Idaho, transparent pixels everywhere else
  2. Read and store some kind of bitmap for this Idaho state image
  3. For each opaque pixel location in the Idaho state image, copy the corresponding pixel from the Idaho state flag image and place it on a blank, transparent canvas

Step 1 would obviously be done manually, but the rest would be done programatically. I think I have the right idea in general but I don't know how I'd approach the specifics. Can anyone point me in the right direction?

As far as implementation technology goes, I'm a PHP guy, so using gdLibrary or something that works with PHP would probably be the best way for me to go.

+2  A: 

The usual way to do something like this would be to use white (all 1's) and black (all 0's) for your outline instead of transparent and opaque. Then you AND that image with the image you're trying to crop. The result is 0's where the outline image had 0's, and the other image where the outline had 1's.

You may also need to invert your outline image, and AND the inverted version with the background image. Then you OR the background image with the foreground image to produce a composite of the foreground image in the shape of Idaho (to use your example) and the background image everywhere else.

Depending on the capabilities of the library you're using, there's a good chance that kind of capability is directly available though. Just for example, Windows has this capability in the MaskBlt function.

Jerry Coffin
+2  A: 

I would think it would be much easier to do by simply adding a bitmask or alpha channel. In that case you would use a negative mask image of your shape and then simply apply it to he regular image as a mask and then save out in a transparent format. Ive never actually done this with GD or ImageMagick but i would think its available as Jerry suggests.

Acutally here is a blog post form a similar SO question that might help: http://about.phalacee.com/geek/creating-mask-layers-using-php-gd

prodigitalson
+1  A: 

In php using ImageMagick is probably your best bet:

$source = IMagick("sourcefile");
$mask = IMagick("maskfile");
$mask->adaptiveResizeImage($source->getImageWidth(), $source->getImageHeight(), true);
$source->compositeImage($mask, imagick::COMPOSITE_MULTIPLY, 0, 0);
$source->writeImage("newfile");
$source->clear();
$source->destroy();

sourcefile must be the source image as you like, maskfile must be a mask file that has the alpha channel set correctly for the shape you want.

wich