I need some help with my implementation of JCrop. I tried to follow the manual but whenever I select an area, it's not actually selecting what I have selected. Instead it's taking some area outside my selection. Sometimes, it's taking the area almost properly (I am thinking because of the photo size) but mostly it's taking wrong area. Please help. Here's my code:
Note $photo is the uploaded image. It's being uploaded properly so no issue on that.
The 120 x 120 is the pixels I want to save the uploaded pictures to so as to save storage space. Also, here's the css of the <img> element where I display the image for cropping:
max-width: 100%;
height: auto;
display: inline-block;
position: relative;
Here's my php code:
$twidth = 120;
$theight = 120;
$quality = 90;
$src = imagecreatefromjpeg($photo);
$dst = ImageCreateTrueColor($twidth, $theight);
$x = $_POST['x'];
$y = $_POST['y'];
$w = $_POST['w'];
$h = $_POST['h'];
imagecopyresampled($dst, $src, 0, 0, $x, $y, $twidth, $theight, $w, $h);
imagejpeg($dst, $photo, $quality);
The problem here is that you are resizing the image box with css. This is creating difficulties for the script to find the correct area.
Instead you should limit the box width/height with Jcrop function as below:
$('#cropbox').Jcrop({
boxWidth: 480, //Maximum width you want for your bigger images
boxHeight: 480, //Maximum Height for your bigger images
...
});
If you use this Jcrop setting it would take the wanted area, otherwise it is not working as expected.
Best wishes
Related
I have a jpg on my server. I use
imagecreatefromjpeg($imgPath);
to open it. I want to make it a 16x9 image by adding black bars to either the top+bottom or left+right. (Think background-size: contain; background-position: center;) This is all I have:
$img_info = getimagesize($imgPath);
I know I need to use ImageCreateTrueColor to make the blank image, imagecopyresampled to create the image, and imagejpeg to save it. But I have no idea how to put them together. Thanks!
This will do the trick:
$im=imagecreatefromjpeg ($imgPath);
$width=ImageSX($im); $height=ImageSY($im); $ratio=16/9;
$width_out=$width; $height_out=$height;
if ($height_out*$ratio<$width_out) {$height_out=floor($width_out/$ratio);} else {$width_out=floor($height_out*$ratio);}
$left=round(($width_out-$width)/2);
$top=round(($height_out-$height)/2);
$image_out = imagecreatetruecolor($width_out,$height_out);
$bg_color = ImageColorAllocate ($image_out, 0, 0, 0);
imagefill($image_out,0,0,$bg_color);
imagecopy($image_out, $im, $left, $top, 0, 0, $width,$height);
imagejpeg($image_out);
How it works: you create the $im container, and check for width and height.
After this, the script checks which side is smaller than the other (multiplied / divided by the ratio) and adjust the output size.
Calculate where the original image should be placed (center alignment) by dividing the difference between the original and the output image dimensions by 2.
Copy over the original image at the given position
Output, done.
I asked in past, but I am not sure we understand & I still havent solution.
I need elegant solution when;
I have photo 600x800 & I need show it on my site rotated on 90 degrees, so result will be, when I print php page all photos will be verticaly automaticly.
e.g.
I have a lot of photos, two kinds: 800x600 & 600x800.
I need on my php page showed all of them 800x600 in original and all 600x800 rotated on 90 degrees.
I need some really simple solution, I am out of mind totally. Some function which can rotate images which have bigger width than height.
Thanks a lot.
Using PHP function getimagesize() you can get width and height of your image:
list($width, $height) = getimagesize($imageUrl);
Then, in your template:
<?php if($width > $height): ?>
//put css here as you want
<?php else: ?>
//put css here as you want
<?php endif; ?>
Use getimagesize for detect image width and if width is 800px add inline css like this
style="-moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg);"
getimagesize() function will give you width and height and by using imagerotate() you can rotate that image to any desired angle.
Try this:-
<?php
// File and rotation
$filename = 'php.jpg';
$degrees = 180;
// Content type
header('Content-type: image/jpeg');
// Load
$source = imagecreatefromjpeg($filename);
// Rotate
$rotate = imagerotate($source, $degrees, 0);
// Output
imagejpeg($rotate);
// Free the memory
imagedestroy($source);
imagedestroy($rotate);
?>
I have two images. one is a jpg image of a rotated polaroid frame polaroid.jpg. The other is just an ordinary image image.jpg.
I'm trying to rotate the image, and then put it on top of the polaroid-image, and then show the merged images as one jpg-image.
I think I'm pretty close with the following code, but I can't manage to get the transparancy working. The uncovered zone of the rotated image is black instead of transparent. What am I doing wrong? I've added a comment to the lines that are relevant for getting a transparent background for the top-image.
$bg_src = "polaroid.jpg";
$img_src = "image.jpg";
$outputImage = imagecreatefromjpeg($bg_src);
$img = imagecreatefromjpeg($img_src);
// This should create transparent background.
$bgd_color = imagecolorallocatealpha($img, 0, 0, 0, 127);
// This should assign the transparent background to the uncovered zone after rotation
$img = imagerotate($img, 10, $bgd_color);
// This should make sure the alpha transparency gets saved
imagesavealpha($img, true);
$img_x = imagesx($img);
$img_y = imagesy($img);
imagecopymerge($outputImage,$img,156,50,0,0,$img_x,$img_y,100);
header('Content-type: image/jpeg');
imagejpeg($outputImage);
imagedestroy($outputImage);
Figured it out after some heave searching. Turns out to be real simple.
I just changed this line:
imagesavealpha($img, true);
to this:
imagecolortransparent($img,$bgd_color);
yay! :)
My code so far (it creates an overlay to a youtube thumbnail):
<?php
header("Content-type:image/png");
$background=imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
$insert=imagecreatefrompng("play.png");
imagecolortransparent($insert,imagecolorat($insert,0,0));
$insert_x=imagesx($insert);
$insert_y=imagesy($insert);
imagecopymerge($background,$insert,5,57,0,0,$insert_x,$insert_y,100);
imagepng($background,NULL);
The output image is 120x90px, but i need it to have 90x90px.
Anyone knows how this is possible?
Thanks in advance!
http://www.johnconde.net/blog/cropping-an-image-with-php-and-the-gd-library/
<?php
header("Content-type:image/png");
$background = imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
$insert = imagecreatefrompng("play.png");
imagecolortransparent($insert,imagecolorat($insert,0,0));
list($current_width, $current_height) = getimagesize($background);
$left = 0;
$top = 0;
$crop_width = 90;
$crop_height = 90;
$canvas = imagecreatetruecolor($crop_width, $crop_height);
$current_image = $background;
imagecopy($canvas, $current_image, 0, 0, $left, $top, $current_width, $current_height);
imagecopymerge($canvas,$insert,5,57,0,0,$current_width,$current_height,100);
imagepng($canvas);
?>
try that it should work if not comment as to otherwise.
This is taken from a function I wrote to create square thumbnails. You may find the commentary I wrote for myself helpful. Depending on your needs (i.e if you can't afford to make assumptions about the type and dimensions of incoming images) you may need to add additional checks. To avoid smashed or stretched thumbnails we take a central part of the image which is most likely to contain something distinguishable as source co-ordinates.
The basic idea is: Since imagecopyresampled or imagecopyresized also allow you to specify destination and source coordinates, you can copy only part of your original image to a new canvas and save that (or directly output to browser). To avoid smashed or stretched dimensions we take a central part of the original image which is most likely to contain distinguishable content.
//assuming you have already merged your $background image with your overlay at this point
//original dimensions
$original_width = imagesx($background);
$original_height = imagesy($background);
//new dimensions
$new_width = 90;
$new_height = 90;
//the center of the rectangular image
$center = $original_width/2, $original_height/2
//the coordinates from where to start on the original image
//assuming you want to crop the center part
$src_x = floor(($original_width/2) - ($new_width/2));
$src_y = floor(($original_height/2) - ($new_height/2));
//create a new canvas with the new desired width, height
$temp = imagecreatetruecolor(90,90);
//copy the large image to this new canvas
imagecopyresampled($temp,$background,0,0,$src_x,$src_y,$new_width,$new_height,$original_width,$original_height);
//from right to left: source image, destination image, dest x, dest y,
//source x, source y, new width, new height, original width, original height
//save the canvas as an image
imagepng($temp);
This could be improved to handle larger images by first taking a central part relative to it's size and then scaling it down to the new canvas.
I am working on improving one of my Facebook apps by allowing the user to upload an image and apply a styled border, or frame to it (i.e. clouds, stars, sky etc). The user chould also be able to save the image, with the border after it has been applied. This explains a little better what I need:
http://zbrowntechnology.info/ImgDisp/imgdisp.php
If you have any other questions or need more details, please let me know.. I'll edit this post.
Use imagecopy(). The example on that page is done using the transparency option with imagecopymerge() but I don't think you need that.
Using imagecopy() you'll specify the X/Y coordinates to use for positioning:
imagecopy( $borderimage, $topimage, 20, 20, 0, 0, $width, $height);
Where $width and $height will be the entire width and height of the top image. You'll want to replace 20 and 20 with the measurement for how much of the border image will be showing around the borders. You will probably have to resize the top image to the exact dimensions you want, or else it might overlap the border a little too far to the right or bottom. (see imagecopyresampled())
Edit:
Here's a rough way to do the whole process (assuming chosenborder.png is the border they chose, and uploadedimage.png is the image they uploaded. If it's a different image type you'll use the corresponding function).
$borderx = 20; // The width of our border
$border = imagecreatefrompng("chosenborder.png");
$topimage = imagecreatefrompng("uploadedimage.png");
$bordersize = getimagesize($border);
$topimagesize = getimagesize($topimage);
/* The new dimensions of topimage. $borderx*2 means we account for
the border on both left and right, top and bottom. */
$newx = $bordersize[0] - ($borderx*2);
$newy = $bordersize[1] - ($borderx*2);
imagecopyresampled( $topimage_scaled, $topimage, 0, 0, 0, 0,
$newx, $newy, $topimagesize[0], $topimagesize[1]);
/* Merge the images */
imagecopy( $border, $topimage_scaled, $borderx, $borderx,
0, 0, $width, $height);
/* Output the image */
imagepng($border, "newimage.png");
/* Free up the memory occupied by the image resources */
imagedestroy($border);
imagedestroy($topimage);
After the user uploads their image, find chosenborder.png and uploadedimage.png, run the above script, then display newimage.png to the user and you're good to go. Just make sure you call imagedestroy() on the temporary image resources or they'll eat up memory.
If you don't want to keep the generated image on your server, you can omit the second argument to imagepng() which will make it send the image information directly as an image to the browser, in which case you'll want to write the correct image HTTP headers.
Client-side solution by using css3:
checkout the css3 property border-image
(dosen't meet the requirement of saving the img with the border)
Server-side solution by merging 2 different images:
<?php
$imgFile = 'img.jpg';
$brdFile = 'brd.jpg';
$img = addBorder($imgFile,$brdFile);
outputImage($img);
function addBorder($imgFile,$brdFile)
{
$img=imagecreatefromjpeg($imgFile);
$brd=imagecreatefromjpeg($brdFile);
$imgSize = getimagesize($imgFile);
$brdSize = getimagesize($brdFile);
//NOTE: the border img MUST be bigger then the src img
$dst_x = ceil(($brdSize[0] - $imgSize[0])/2);
$dst_y = ceil(($brdSize[1] - $imgSize[1])/2);
imagecopymerge ( $brd, $img, $dst_x, $dst_y, 0, 0, $imgSize[0], $imgSize[1] ,100 );
return $brd;
}
function outputImage($img)
{
header('Content-type: image/png');
imagepng($img);
}
?>