Hi Everyone (this is my first post),
I am trying to figure a way of cropping a polygon out of an image. I have been reading other similar code. It seems that most code is based around the following process:
Resize the image to fit the width and height of the polygon shape,
Create a blank image of an unusual colour the same size,
Overlay transparent pixels in the shape of the polygon,
Overlay that on to the resized image
Set the unusual colour to be transparent...
My problem is I do not want the code to be reliant on the unusual colour not being in the original image. Does anyone have a better method or some code which I can use to check if the unusual colour is in the image.
On a side note once I have cropped them I am looking to add a border only around the top and the left sides of the shape and three pixels in the corners to achieve a rounded corner effect... if anyone has any ideas about that then please also post.
If you draw the polygon in black-white (and brey values between) on a different image (called mask), you can use applyMask of the WideImage library.
See:
- http://wideimage.sourceforge.net/
- http://wideimage.sourceforge.net/wp-content/current/demo/index.php?demo=applyMask&output=preset%20for%20demo&colors=255&dither=&match_palette=
an alternative way would be to cut the big image in 4 parts ...
a top part,
left side and right side that are the parts on the left and right of the image afte the mask
and bottom part
and recompose them.
But that would require a bit of code and calculations.
Related
I want to convert a multipages PDF to a series of png files, while the PDF is portrait and png file is landscape, using imagemagick. I have achieve the conversion from PDF portrait to png protrait(code attached below). But have no idea how to make portrait image to landsacpe with no distortion, (not rotate the image).
Can anyone kindly help me? Thanks.
$infile=$direcory."/Test.pdf";
$images=new Imagick();
$bodercolor=new ImagickPixel("white");
$images->setResolution(220, 220);
$images->readimage($infile);
$images->setimageformat("png");
foreach ($images as $i=>$image){
//set backgroud color = white
$image->setimagebordercolor($bodercolor);
$image->borderimage($bodercolor, 0, 0);
$image->writeimage($direcory."/test-pg".$i.".png");
}
$images->clear();
$images->destroy();
Actually, what I want is rotate the vertical page to horizontal with the objects on it have almost no changes. Like what we are able to do using Microsoft Word/PowerPoint when you change page orientation to landscape.
When you change a slide's orientation in PowerPoint, it recomputes the whole layout: centered elements are shifted left or right based on the new width, multi-line text is re-wrapped, and so on. This is possible because PowerPoint knows how the elements are supposed to be formatted.
You can't do that with a PDF file because it doesn't contain that kind of high-level formatting information; a PDF is basically just a description of where to put ink on paper. Reading a PDF file, you don't know that a particular line of text is supposed to be centered; you just know the (X, Y) coordinates where its top-left corner should be positioned. If one line of text appears below another, there's nothing that tells you whether words at the beginning of the second line should be moved to the end of the first when the page gets wider (e.g. word-wrapping) or if they're unrelated items (like separate bullet points) that should not be combined.
Fundamentally, a PDF is more like a picture than an editable document.
Well, your task then seems to be two steps: gettng png from pdf (which you say you have done) and getting png image to change sizes.
Question yourself what do you want to do - rotate the vertical image to be horizontal? Crop some part of the vertical image and fit it into horizontal space?
What you need to do is to decide the answer to the above question. After that - take a pen, piece of paper and draw the process. Draw the vertical rectangle, then fill in some area that is you content on that page, then rotate/transform/resize/fit and etc - whatever your answer was that content area into horizontal rectangle.
After that you can write your code - deal with pixel width/height, rotation angle, fitting the area to the horizontal space and etc.
I have a problem with image manipulation in php. As they say, a picture paints a thousand words so below is an image to assist me in explaining my situation.
I have a canvas (the picture of a car) and a container (the red rectangle) and the image above is my initial setup. Here are the details that I know about my initial setup:
Dimension of the canvas (width & height)
Dimension of the container (width & height)
Position of the container relative to the top left of the canvas (x, y)
Next I apply a rotation on the canvas at a certain angle counter-clockwise. Assuming the centre of the rotation is the centre of the canvas itself.
As of this step, I know 2 additional details:
The angle of the rotation
The direction of the rotation (counter-clockwise)
Things to take note of:
The container itself didn't rotate, just the canvas.
The dimension of the canvas may have changed. In this case, both the width and height of the canvas have increased.
Details that I DO NOT know anymore AFTER the rotation:
Dimension of the canvas
Position of the container relative to the top left of the canvas
Then, the container is used to crop the canvas at its current position. The image below is the result I'm trying to achieve using php.
I have never done any image manipulation in php before. Code examples are greatly appreciated.
I found the answer here
Crop and rotate images with JS and PHP
I didn't know that we have to manually get the dimension of the canvas after the rotation and recalculate the relative position of the container based on the new canvas dimension.
Andy Croxall wrote a really good overview of image manipulation with PHP on Smashing Magazine:
http://coding.smashingmagazine.com/2011/04/05/image-manipulation-with-jquery-and-php-gd/
But I wouldn't bother reinventing the wheel here - Cloudinary pretty much did all the work for you. They even have a free 500MB plan you can use to test it out and compare results. Here's an overview of their image manipulation capabilities:
http://cloudinary.com/features#image_manipulation
Good luck !
Ohad
I've got a jpg image and I want to return the same image, with a "highlight" effect.
Basically, I want to pass the script the xy coords, and redraw the image darkened, with an ellipse that remains in the original colouring.
Initially I did this by creating a second image, same dimensions, and drawing a white elipse, then merging them together at 40% or so. The effect works, but the "highlighted" area is obviously a bit washed out.
Anyone know how I can basically delete that ellipse so it is purely transparent and then merge it on top of the original for a clear highlight?
You can use a png for the second image with the elipse being completely transparent while the area that you want darkened has an alpha of 20% (or whatever works best). When you merge the images, you can use imagecopy instead of imagecopymerge as the alpha (transparent) value is included in the second image already.
Mhh, kinda hard to explain with my poor english ;)
So, lets say I have an image, doesnt matter what kind of (gif, jpg, png) with 200x200 pixel size (total area 40000 pixels)
This image have a background, that can be trasparent, or every color (but i know the background-color in advance).
Lets say that in the middle of this image, there is a picture (for keep the example simple lets suppose is a square drawn), of 100x100 pixels (total area 10000 pixels).
I need to know the area percentage that the small square fill inside the image.
So, in i know the full image size and the background-color, there is a way in php/python to scan the image and retrieve that (in short, counting the pixel that are different from the given background)?
In the above example, the result should be 25%
EDIT: this are two image as example (gimped oin the way ;):
I need to know the percentage of the green pepper in the whole image (that is 400x400)
from PIL import Image
image = Image.open("pepper.png")
bg = image.getpixel((0,0))
width, height = image.size
bg_count = next(n for n,c in image.getcolors(width*height) if c==bg)
img_count = width*height - bg_count
img_percent = img_count*100.0/width/height
gives 7.361875 for both images
I am assuming the surrounding area has only one colour and the object in the image can have any shape (so you need to find out its coordinates first, right?)
If you can use ImageMagick, it's easy.
Store size of image (40000 Pixels)
Send image to ImageMagick and trim the surrounding area using -trim (description here)
Compare size of resulting image (10000 Pixels) with that of original image
If you can't use ImageMagick, you will have to use GD to crop the surrounding area away. A rough description is in the answer to this question. I'm pretty sure this has been implemented in PHP already, though.
Using Python and PIL (Python Imaging Library) you could try the following (untested - credit goes to the original thread here):
from PIL import ImageChops
def trim(im, border):
bg = Image.new(im.mode, im.size, border)
diff = ImageChops.difference(im, bg)
bbox = diff.getbbox()
if bbox:
return im.crop(bbox)
else:
# found no content
raise ValueError("cannot trim; image was empty")
And then do your calculations based on width * height (before and after the trim).
It depends a bit on your accuracy requirements and on the presence of the background color in the image. Consider this annoying test case:
Make a 400 pt large "G".
Make the text white. Hit "Shadow" or "Outline" so it surrounded by black.
Put it on a white background.
Pick your effort:
You can get a bounding box, which heavily overestimates the size of the 'G' because
of the large blank space inside.
You can count the white pixels, which heavily underestimates the size of the 'G' because of the many white pixels inside the outline.
You can pick a color not in the image, like blue, and run a recursive painter's algorithm from the top left corner. Then you can accurately count the blue pixels.
There are faster methods, which are more complicated.
You can usually use PIL (Python Imaging Library) http://www.pythonware.com/products/pil/ to access raw image data from the file formats.
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:
Create an image that has opaque pixels for the shape of Idaho, transparent pixels everywhere else
Read and store some kind of bitmap for this Idaho state image
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.
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
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.
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.