• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6932
  • Last Modified:

Crop image into a circle

I would like to take a square image then with PHP crop the edges to make it a circle.

Is this possible? google hasnt helped me find a solution.
0
nooc
Asked:
nooc
  • 11
  • 6
  • 2
  • +1
1 Solution
 
jamespbyrneCommented:
There are a few ways i can think of to do this, you could take a image that is circular and white for example, then it can take that image and put it over the top of the other images in specified locations using the GD package in php.

Also i did a good search and came up with this script which will round the corners on a image, you can edit the radius on this, and that might accomplish what you need. The link is below.

Link: http://www.assemblysys.com/dataServices/php_roundedCorners.php
0
 
NerdsOfTechTechnology ScientistCommented:
Created by NerdsOfTech and tested by NerdsOfTech
Layer approach using PHP GD
<?php
// Created by NerdsOfTech
 
// Step 1 - Start with image as layer 1 (canvas).
$img1 = ImageCreateFromjpeg("./fractal.jpg"); // change this to your image path
$x=imagesx($img1)-$width ;
$y=imagesy($img1)-$height;
 
 
// Step 2 - Create a blank image.
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255); // white background
imagefill($img2, 0, 0, $bg);
 
 
// Step 3 - Create the ellipse OR circle mask.
$e = imagecolorallocate($img2, 0, 0, 0); // black mask color
 
// Draw a ellipse mask
// imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
 
// OR 
// Draw a circle mask
$r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
 
 
 
// Step 4 - Make shape color transparent
imagecolortransparent($img2, $e);
 
 
 
// Step 5 - Make shape color transparent
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
 
 
 
// Step 6 - Output merged image
header("Content-type: image/png"); // output header
imagepng($img1); // output merged image
 
 
// Step 7 - Cleanup memory
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
?>

Open in new window

0
 
NerdsOfTechTechnology ScientistCommented:
Perfected with corrected comments

=NerdsOfTech
<?php
// Created by NerdsOfTech
 
// Step 1 - Start with image as layer 1 (canvas).
$img1 = ImageCreateFromjpeg("./fractal.jpg"); // change this to your image path
$x=imagesx($img1)-$width ;
$y=imagesy($img1)-$height;
 
 
// Step 2 - Create a blank image.
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255); // white background
imagefill($img2, 0, 0, $bg);
 
 
// Step 3 - Create the ellipse OR circle mask.
$e = imagecolorallocate($img2, 0, 0, 0); // black mask color
 
// Draw a ellipse mask
// imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
 
// OR 
// Draw a circle mask
$r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
 
 
 
// Step 4 - Make shape color transparent
imagecolortransparent($img2, $e);
 
 
 
// Step 5 - Merge the mask into canvas with 100 percent opacity
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
 
 
 
// Step 6 - Output merged image
header("Content-type: image/png"); // output header
imagepng($img1); // output merged image
 
 
// Step 7 - Cleanup memory
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
?>

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
NerdsOfTechTechnology ScientistCommented:
Uber-perfected with border outside of image circle transparent...

>:)

=NerdsOfTech
<?php
// Created by NerdsOfTech *please keep creation reference *
 
// Step 1 - Start with image as layer 1 (canvas).
$img1 = ImageCreateFromjpeg("./fractal.jpg");
$x=imagesx($img1)-$width ;
$y=imagesy($img1)-$height;
 
 
// Step 2 - Create a blank image.
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255); // white background
imagefill($img2, 0, 0, $bg);
 
 
// Step 3 - Create the ellipse OR circle mask.
$e = imagecolorallocate($img2, 0, 0, 0); // black mask color
 
// Draw a ellipse mask
// imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
 
// OR 
// Draw a circle mask
$r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
 
 
 
// Step 4 - Make shape color transparent
imagecolortransparent($img2, $e);
 
 
 
// Step 5 - Make shape color transparent
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
 
// Step 6 - Make outside frame color transparent
imagecolortransparent($img1, $bg);
 
// Step 7 - Output merged image
header("Content-type: image/png"); // output header
imagepng($img1); // output merged image
 
 
// Step 8 - Cleanup memory
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
?>

Open in new window

0
 
NerdsOfTechTechnology ScientistCommented:
ULTRA-Uber-perfected with border outside of image circle transparent and corrected commends...

>:)

=NerdsOfTech
<?php
// Created by NerdsOfTech
 
// Step 1 - Start with image as layer 1 (canvas).
$img1 = ImageCreateFromjpeg("./fractal.jpg");
$x=imagesx($img1)-$width ;
$y=imagesy($img1)-$height;
 
 
// Step 2 - Create a blank image.
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255); // white background
imagefill($img2, 0, 0, $bg);
 
 
// Step 3 - Create the ellipse OR circle mask.
$e = imagecolorallocate($img2, 0, 0, 0); // black mask color
 
// Draw a ellipse mask
// imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
 
// OR 
// Draw a circle mask
$r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e); 
 
 
// Step 4 - Make shape color transparent
imagecolortransparent($img2, $e);
 
 
// Step 5 - Merge the mask into canvas with 100 percent opacity
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
 
 
// Step 6 - Make outside border color around circle transparent
imagecolortransparent($img1, $bg);
 
 
// Step 7 - Output merged image
header("Content-type: image/png"); // output header
imagepng($img1); // output merged image
 
 
// Step 8 - Cleanup memory
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
?>

Open in new window

0
 
noocAuthor Commented:
You're a legend, worked like a charm :)
0
 
noocAuthor Commented:
one more thing if you're still there, ive exported to file with

imagepng($img1,'testresult.png',0,NULL);

but the background is white, not transparent, how do i make the back transparent?
0
 
NerdsOfTechTechnology ScientistCommented:
try without quality parameters

imagepng($img1,'testresult.png');

Open in new window

0
 
addmarketingCommented:
The transparency doesnt work for me either, even if I save it with out the qaulity option what should I do all images have corners
0
 
NerdsOfTechTechnology ScientistCommented:
addmarketing,
use my accepted solution for your for your test. Try it raw on your server to see if it works WITHOUT ANY ALTERATION TO THE CODE. TEST IT. Then modify it.

if you pass any other parameter to imagepng() other than ($img1, 'filename.png' you may have an issue!

ALSO make sure that the output is PNG!
AND that the filename is *.png

0
 
addmarketingCommented:
Thank you for replying well if you save image out of browser its not transparent I tried 2 methods to get image on 3 browsers. I need to save it as a image tried that as well then when ever I bring into photoshop or flash I get no transparency. Depending on what browser I pulled it from it would have a different color back or corners. I need them to be save as images because thats what my application requires. I tried with no quality with quality with a ton over other functions as well and another tutorial I found on a another site which they do things a little bit different on how to find the colors. Im attaching the other script I found. Does anyone know if this is even possible? I can seem to find one example that actually works.
$original_image = './image.png';
$output_image = './new.png';
$temp_image = './temp'; // path and name (don't include the extension)
$is_true_color = true;
 
$ext = substr ( $original_image, strrpos ( $original_image, '.' ) );
$temp_image .= $ext;
$new = image_get ( $ext, $original_image );
$width = imagesx ( $new );
$height = imagesy ( $new );
 
// we need to create temp reduced image so we can get the colors
// in a high bit true color image (png 16,24 bit only)
 
if ( $is_true_color )
{
    imagetruecolortopalette ( $new, false, 256 );
    image_make ( $new, $ext, $temp_image );
    imagedestroy ( $new );
    $colors = get_rgb ( $temp_image, $ext );
    @unlink ( $temp_image );
    $new = image_get ( $ext, $original_image );
}
else
{
    $colors = get_rgb ( $original_image, $ext );
}
 
// this creates the cutout layer (2 colors, both will become transparent)
 
$old = imagecreate ( $width, $height );
imageantialias( $old, true );
imagecolorallocate ( $old, $colors[0]['red'], $colors[0]['green'], $colors[0]['blue'] );
$bg = imagecolorallocate ( $old, $colors[1]['red'], $colors[1]['green'], $colors[1]['blue'] );
imagefilledellipse ( $old, floor ( $width / 2 ), floor ( $height / 2 ), $width, $height, $bg );
imagecolortransparent ( $old, $bg );
imagecopy ( $new, $old, 0, 0, 0, 0, $width, $height );
image_make ( $new, $ext, $output_image );
imagedestroy ( $old );
imagedestroy ( $new );
 
// this layers both images together, making a nice ellipse/round transparent image cutout
 
$old = imagecreate ( $width, $height );
$new = image_get ( $ext, $output_image );
$tbg = imagecolorallocate ( $old, $colors[0]['red'], $colors[0]['green'], $colors[0]['blue'] );
imagecopy ( $old, $new, 0, 0, 0, 0, $width, $height );
imagecolortransparent ( $old, $tbg );
image_make ( $old, $ext, $output_image );
imagedestroy ( $old );
imagedestroy ( $new );
 
/*
* shortcut functions (1,2)
*/
 
// returns the called image resource
 
function image_get ( $ext, $name )
{
    switch ( $ext )
    {
        case '.gif' :
        return ( imagecreatefromgif ( $name ) );
        break;
        case '.png' :
        return ( imagecreatefrompng ( $name ) );
        break;
    }
}
 
// outputs the image named passed to it
 
function image_make ( $io, $ext, $name )
{
    switch ( $ext )
    {
        case '.gif' :
        imagegif ( $io, $name );
        break;
        case '.png' :
        imagepng ( $io, $name );
        break;
    }
}
 
// get (2) colors not found in the current image
 
function get_rgb ( $image, $ext )
{
    $x = 0;
    $colors = array ();
    $img = image_get ( $ext, $image );
 
    for ( $color = 10; $color <= 250; $color++ )
    {
        if ( imagecolorexact ( $img, $color, $color, $color ) == -1 )
        {
            $colors[] = array ( 'red' => $color, 'green' => $color, 'blue' => $color );
 
            if ( $x == 1 )
            {
                imagedestroy ( $img );
                return ( $colors );
            }
 
            $x++;
        }
    }
 
    imagedestory ( $img );
    return ( $colors );
}

Open in new window

0
 
NerdsOfTechTechnology ScientistCommented:
If you use my raw script you can FTP the image out of your directory after it is created... if you are using it.
0
 
NerdsOfTechTechnology ScientistCommented:
Try using GIMP to open the image its a free cross platform image program
0
 
addmarketingCommented:
I tried ftp'ing the image out as well no luck, I played with gimp back in the day on a debian machine I think it doesnt even compare to photoshop cs4. If I ftp it out I always get white corners. Since im on a Mac I can see some sort of transparency when u drag the image when I use the browser method, if I change the blending options when I drag it you can see white corners so to some what of a degree that works possibly, but when you save it no matter which way you grab the file it wont open up with transparency. What I was thinking as a possible work around would be to take a transparent blank and try doing a image merge maybe while using the functions below.

imagesavealpha($img1, true);
and imagealphablending();

have you tested the script when trying to save a image? If you have I wold really like to see the image you created. Also wanted to think you for your feedback.
0
 
addmarketingCommented:
I have some transparent images that are png that I put on another site I can ctrl click image and click save as and open it in photoshop and it reserves transparency when I ctrl click the dynamic image and save as and open in photoshop white corners. Im using safari on mac. So this means script doesnt make transparent images...  The closes thing I can find for reference on http://us3.php.net/imagealphablending
0
 
NerdsOfTechTechnology ScientistCommented:
The script produces transparency correctly...

Here is my round image proof (attached) and the screenshot (attached) of the image with the funky background color showing through...

Maybe Photoshop is the issue.

I was given the points for a reason :)

=NerdsOfTech
round2.png
screenshot.jpg
0
 
addmarketingCommented:
After lots of playing around with and testing. I came to a conclusion yours works if rendered live I tried changing the background color everything it worked, but when you save the image it wont save transparency after looking through many forums I found the work around was to run this command on the image you saved.


exec("/usr/local/bin/convert start_image.jpg -transparent red output_image.png");


I still haven't tested it but looks valid to me im going to check out the man pages later today on the convert program. The first image you posted with transparency doesnt load in photoshop if you check out rockthedash.com listen & vote page "a site i just finished" and take one of those round skittle off with save as it keeps its transparency when open in photoshop which the png was made in photoshop. Your image as well as all my images have the ellipse outside border color when ever brought into photoshop. I think this is a bug with gd library and there more to png maybe with layering or channels ect... that some programs support and some dont. Something imbedded in the image is there or not there maybe I should report bug to gd. Anyways I will let you know how the next test goes. Also the main issue that im having is the final destination of png files need to goto flash the dynamic images created via the php have white corners in there as well but if I use a image loader with my photoshopped file they dont.

0
 
NerdsOfTechTechnology ScientistCommented:
Try this script instead.

Source: php.net
<?php
 
$image = "v.png";
$corner = 40;
 
file_exists($image) or die("No such file: ".$image); //check if image exists before processing
 
$dim = getimagesize($image);
 
//create from type handle
if($dim[2] == 1) $new = imagecreatefromjpeg($image);
elseif($dim[2] == 2) $new = imagecreatefromgif($image);
elseif($dim[2] == 3) $new = imagecreatefrompng($image);
else die("Unsupported format: ".$dim[2]);
 
//find colorcode
$palette = imagecreatetruecolor($dim[0], $dim[1]);
$found = false;
while($found == false) {
   
    $r = rand(0, 255);
    $g = rand(0, 255);
    $b = rand(0, 255);
   
    if(imagecolorexact($new, $r, $g, $b) != (-1)) {
       
        $colorcode = imagecolorallocate($palette, $r, $g, $b);
        $found = true;
           
    }
   
}
 
//draw corners
imagearc($new, $corner-1, $corner-1, $corner*2, $corner*2, 180, 270, $colorcode);
imagefilltoborder($new, 0, 0, $colorcode, $colorcode);
 
imagearc($new, $dim[0]-$corner, $corner-1, $corner*2, $corner*2, 270, 0, $colorcode);
imagefilltoborder($new, $dim[0], 0, $colorcode, $colorcode);
 
imagearc($new, $corner-1, $dim[1]-$corner, $corner*2, $corner*2, 90, 180, $colorcode);
imagefilltoborder($new, 0, $dim[1], $colorcode, $colorcode);
 
imagearc($new, $dim[0]-$corner, $dim[1]-$corner, $corner*2, $corner*2, 0, 90, $colorcode);
imagefilltoborder($new, $dim[1], $dim[1], $colorcode, $colorcode);
 
imagecolortransparent($new, $colorcode); //make corners transparent
 
//display rounded image
header("Content: image/png");
imagepng($new);
imagedestroy($new);
 
?> 

Open in new window

0
 
addmarketingCommented:
K well I got it to work with photoshop and import to flash with the previous function I posted above your method is buggy theres a bug with gd library where transparency doesn't show up for all programs only some if you use the convert function it will open up in all applications with a transparency I been working on this issue for 3 days and I have 10 years experience finally figured a solid workaround, if you use this cammand with the same color code u used to fill the object circ or ellipse it is bug free!!!!!!!!


exec("/usr/local/bin/convert start_image.jpg -transparent red output_image.png");


Works!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0
 
NerdsOfTechTechnology ScientistCommented:
Wow nice! Can you post the finished code this will be great for this thread's archives.

Best regards,
=NerdsOfTech
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 11
  • 6
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now