I'm trying to build a function that takes a PHP image resource and places it in the center of a new image of predetermined size. I do not want to scale the image; rather I want to place it as-is in the center of an enlarged "canvas."
$img is a valid image resource - if I return it I receive the correct original (unprocessed) image. $canvas_w and $canvas_h are the width and height of the desired new canvas. It's creating the correct size canvas, but the contents of the file are unexpectedly solid black when I return the desired "corrected" image resource ($newimg).
// what file?
$file = 'smile.jpg';
// load the image
$img = imagecreatefromjpeg($file);
// resize canvas (not the source data)
$newimg = imageCorrect($img, false, 1024, 768);
// insert image
header("Content-Type: image/jpeg");
imagejpeg($newimg);
exit;
function imageCorrect($image, $background = false, $canvas_w, $canvas_h) {
if (!$background) {
$background = imagecolorallocate($image, 255, 255, 255);
}
$img_h = imagesy($image);
$img_w = imagesx($image);
// create new image (canvas) of proper aspect ratio
$img = imagecreatetruecolor($canvas_w, $canvas_h);
// fill the background
imagefill($img, 0, 0, $background);
// offset values (center the original image to new canvas)
$xoffset = ($canvas_w - $img_w) / 2;
$yoffset = ($canvas_h - $img_h) / 2;
// copy
imagecopy($img, $image, $xoffset, $yoffset, $canvas_w, $canvas_h, $img_w, $img_h);
// destroy old image cursor
//imagedestroy($image);
return $img; // returns a black original file area properly sized/filled
//return $image; // works to return the unprocessed file
}
Any hints or obvious errors here? Thanks for any suggestions.
In place of imagecopy(), this seemed to work:
imagecopymerge($img, $image, $xoffset, $yoffset, 0,0, $img_w, $img_h, 100);
Related
in my project i just do image watermarking or image combine it's working fine and code for that.
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<?php
if(isset($_POST['submit']))
{
// Give the Complete Path of the folder where you want to save the image
$folder="uploads/";
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "$folder".$_FILES["fileToUpload"]["name"]);
$file='uploads/'.$_FILES["fileToUpload"]["name"];
$uploadimage=$folder.$_FILES["fileToUpload"]["name"];
$newname= time();
$ext = pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_EXTENSION);
// Set the thumbnail name
$thumbnail = $folder.$newname.".".$ext;
$imgname=$newname.".".$ext;
// Load the mian image
if ($ext=="png" || $ext=="PNG") {
$source = imagecreatefrompng($uploadimage);
}
else if ($ext=="gif" || $ext=="GIF") {
$source = imagecreatefromgif($uploadimage);
}
else if ($ext=="bmp" || $ext=="BMP") {
$source = imagecreatefrombmp($uploadimage);
}
else{
$source = imagecreatefromjpeg($uploadimage);
}
// load the image you want to you want to be watermarked
$watermark = imagecreatefrompng('uploads/logo1.png');
// get the width and height of the watermark image
$water_width = imagesx($source)/2;
$water_height = imagesy($watermark);
// get the width and height of the main image image
$main_width = imagesx($source);
$main_height = imagesy($source);
$im_middle_w = $main_width/2;
$im_middle_h = $main_height/2;
// Set the dimension of the area you want to place your watermark we use 0
// from x-axis and 0 from y-axis
$dime_x = $im_middle_w - $water_width/2;
$dime_y = $im_middle_h - $water_height/2;
// copy both the images
imagecopy($source, $watermark, $dime_x, $dime_y, 0, 0, $water_width, $water_height);
// Final processing Creating The Image
imagejpeg($source, $thumbnail, 100);
unlink($file);
}
?>
<img src='uploads/<?php echo $imgname;?>'>
</body>
</html>
but problem with setting $water_width and i want set as half of my source image. but when i have source image of less width or more width compare to $water_width it's set it like that. see image when source image width is more.
and when width is less.
so my problem is how to set $water_width as half of source image width?
by Alex your answer it's came up like this.
This will resize watermark to half-width of original image and put it in the centre:
// load the image you want to you want to be watermarked
$watermark = imagecreatefrompng('uploads/logo1.png');
// get the width and height of the watermark image
$water_width = imagesx($watermark);
$water_height = imagesy($watermark);
// get the width and height of the main image image
$main_width = imagesx($source);
$main_height = imagesy($source);
// resize watermark to half-width of the image
$new_height = round($water_height * $main_width / $water_width / 2);
$new_width = round($main_width / 2);
$new_watermark = imagecreatetruecolor($new_width, $new_height);
// keep transparent background
imagealphablending( $new_watermark, false );
imagesavealpha( $new_watermark, true );
imagecopyresampled($new_watermark, $watermark, 0, 0, 0, 0, $new_width, $new_height, $water_width, $water_height);
// Set the dimension of the area you want to place your watermark we use 0
// from x-axis and 0 from y-axis
$dime_x = round(($main_width - $new_width)/2);
$dime_y = round(($main_height - $new_height)/2);
// copy both the images
imagecopy($source, $new_watermark, $dime_x, $dime_y, 0, 0, $new_width, $new_height);
// Final processing Creating The Image
imagejpeg($source, $thumbnail, 100);
imagedestroy($source);
imagedestroy($watermark);
imagedestroy($new_watermark);
You can try imagettftext method, if you don't want any such high perfection in transparency. You can have try of this code. You have to save a font file in your directory, here I used arial.ttf.
$im = imagecreatefrompng("png.png"); //create image data
$font = 'arial.ttf'; //font file name
$randomString = "example.com"; //string need to be shown
$main_width = imagesx($im); //finding width and height
$main_height = imagesy($im);
$posx= $main_width/2; //finding center
$posy = $main_height/2;
$color = imagecolorallocate($im, 200, 200, 200); //Creating color
$size = ($main_width/25)+1; //determine size of font. +1 to avoid 0
$temp = $size*5;
$posx = $posx-$temp; //adjust to average center
imagettftext($im,$size,0, $posx, $posy, $color, $font , $randomString); //apply a text
You have to adjust posx and posy for your text position. Size also can be adjusted with some logics.
$color = imagecolorallocate($im, 0, 0, 0);= black
and $color = imagecolorallocate($im, 255, 255, 255); = white.
You have to adjust this for your required text color.
I want to resize 2 types of images (png, gif) with transparent background...
But in png it works well in big size of the original image.
eg. Original file dimension is 150x150
change into 200x200 or exceeding the original size it works well. but in 100x100 it displays
Then the last GIF it doesn't work.
Here my code for png
$new_img = imagecreatetruecolor($max_w, $max_h);
imagealphablending($new_img, false);
imagesavealpha($new_img, true);
$transparentindex = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
imagefill($new_img, 0, 0, $transparentindex);
imagepng($new_img, $dir);
Here my code for gif
imagegif($new_img, $dir);
I know no PHP, but this seems to do the trick:
#!/usr/local/bin/php -f
<?php
$neww=100;
$newh=100;
// Load original image and get its dimensions
$img = imagecreatefrompng("badge.png");
$w=imagesx($img);
$h=imagesy($img);
// Create output image, and fill with lots of transparency
$out = imagecreatetruecolor($neww,$newh);
imagealphablending($out,false);
$transparentindex = imagecolorallocatealpha($out,0,0,0,127);
imagefill($out,0,0,$transparentindex);
imagesavealpha($out, true);
// Copy original image, reized on top
imagecopyresized($out,$img,0,0,0,0,$neww,$newh,$w,$h);
imagepng($out,"out.png");
?>
Here is a little hack :)
Don't have any other ideas.
It involves a second image (1x1 trasparent gif)
create image
resize
create a transparent background with same size as resized image
use imagecolortransparent() to get the rgb index
imagecopymerge() images
voilĂ
.
$dir = 'http://i.stack.imgur.com/DbhrJ.png';
$max_w = 50;
$max_h = 50;
// get image size
list($src_w, $src_h) = getimagesize($dir);
if ($src_w > $max_w) {
$ratio = $max_w / $src_w;
$max_w = $src_w * $ratio;
}
else if ($src_h > $max_h) {
$ratio = $max_h / $src_h;
$max_h = $src_h * $ratio;
}
// resize image to $max_w and $max_h, and also save alpha
$src = imagecreatefromstring(file_get_contents($dir));
$new_img = imagecreatetruecolor($max_w, $max_h);
imagealphablending($new_img, false);
imagesavealpha($new_img, true);
imagecopyresampled($new_img, $src, 0, 0, 0, 0, $max_w, $max_h, $src_w, $src_h);
// create a new image with $max_w and $max_h
$maxsize = imagecreatetruecolor($max_w, $max_h);
// add 1x1 gif and resize, then copy over $maxsize
$background = imagecreatefromgif("http://i.imgur.com/atRjCdk.gif"); // transparent 1x1 gif
imagecopyresampled($maxsize, $background, 0, 0, 0, 0, $max_w, $max_h, 1, 1);
// allocate transparency
$transparent = imagecolortransparent($maxsize);
$transparent_index = imagecolorallocate($maxsize, $transparent['red'], $transparent['green'], $transparent['blue']);
imagecolortransparent($maxsize, $transparent_index);
// image copy
imagecopymerge($maxsize, $new_img, 0, 0, 0, 0, $max_w, $max_h, 100);
// save or output
imagegif($maxsize, $path_to_save);
// destroy images
imagedestroy($maxsize);
imagedestroy($new_img);
imagedestroy($background);
imagedestroy($src);
I have a resize image script that takes a 130x81 image and adds it to a 130x130 image, when the imagecopyresampled function runs it adds a black background into the space that is left over, even though the base image is white. Code below, I could really appreciate some help.
The image I am trying to merge onto the 130x130 file php created is:
$width = 130;
$height = 130;
$filename = 'process-add.jpg'; //130x81px jpg
$this->_image = imagecreatefromjpeg($filename);
$background = imagecreatetruecolor(130,130);//create the background 130x130
$whiteBackground = imagecolorallocate($background, 255, 255, 255);
imagefill($background,0,0,$whiteBackground); // fill the background with white
imagecopyresampled($background, $this->_image,(130-$width)/2,(130-$height)/2, 0, 0, $width, $height, $width, $height); // copy the image to the background
ImageJpeg ($background,null,100); //display
I have read on multiple posts to add:
imagealphablending($background, false);
into the code which should fix it, but it doesn't make any difference.
Thanks in advance!
This has been solved. The issue was with teh width and height on the imagecopyresampled call. See the code block below:
<?
ini_set('allow_url_fopen', true);
$filename = 'http://img.yessy.com/1402152287-17201a.jpg'; // 130x81
$image = imagecreatefromjpeg($filename);
list($originalWidth, $originalHeight) = getimagesize($filename);
// Size of image to create
$width = 130;
$height = 130;
$background = imagecreatetruecolor($width, $height);//create the background 130x130
$whiteBackground = imagecolorallocate($background, 255, 255, 255);
imagefill($background,0,0,$whiteBackground); // fill the background with white
imagecopyresampled($background, $image, 0, ($height - $originalHeight) / 2, 0, 0, $originalWidth, $originalHeight, $originalWidth, $originalHeight); // copy the image to the background
header("Content-type: image/jpeg");
ImageJpeg ($background,null,100); //display
?>
I'm trying to redesign my site so that my original square, tile-based rendering of images can be more of a cutout of the image... to get rid of that grid pattern.
Here's how it looked originally...
Here's a rough mock-up of what I'm going for:
So I resaved an image thumbnail with a transparent background... I just want the dog to show, and the square is transparent which will show the site's background underneath.
Yet when I render it on the page, it has this black background.
I've checked my CSS to see if there is some sort of img class, or class for the rendered comics... or even the bootstrap to see where there may be a background-color being assigned to black (and also searched for hex code 000000), but didn't find one...
Do you know why this may be happening?
Thanks!
EDIT: I've just noticed something...
My logo at the top renders with a transparent background... and the element is a png file... therefore, its MIME type is image/png.
I'm using a thumbnailing script to make the thumbnails smaller, but now the element is of thumber.php, which puts it as MIME type image/jpeg.
So I guess it's my thumbnailing script that changing the MIME type.
So I checked it, and it's creating the file as a jpeg
//imagejpeg outputs the image
imagejpeg($img);
Is there a way to change it so that the resampled image is output as a png?
Thumbnailing script:
<?php
#Appreciation goes to digifuzz (http://www.digifuzz.net) for help on this
$image_file = $_GET['img']; //takes in full path of image
$MAX_WIDTH = $_GET['mw'];
$MAX_HEIGHT = $_GET['mh'];
global $img;
//Check for image
if(!$image_file || $image_file == "") {
die("NO FILE.");
}
//If no max width, set one
if(!$MAX_WIDTH || $MAX_WIDTH == "") {
$MAX_WIDTH="100";
}
//if no max height, set one
if(!$MAX_HEIGHT || $MAX_HEIGHT == "") {
$MAX_HEIGHT = "100";
}
$img = null;
//create image file from 'img' parameter string
$img = imagecreatefrompng($image_file);
//if image successfully loaded...
if($img) {
//get image size and scale ratio
$width = imagesx($img);
$height = imagesy($img);
//takes min value of these two
$scale = min($MAX_WIDTH/$width, $MAX_HEIGHT/$height);
//if desired new image size is less than original, output new image
if($scale < 1) {
$new_width = floor($scale * $width);
$new_height = floor($scale * $height);
$tmp_img = imagecreatetruecolor($new_width, $new_height);
//copy and resize old image to new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagedestroy($img);
//replace actual image with new image
$img = $tmp_img;
}
}
//set the content type header
header("Content-type: image/png");
//imagejpeg outputs the image
imagealphablending($img, false);
imagesavealpha($img, true);
imagepng($img);
imagedestroy($img);
?>
You will need to make some changes in the image generator and see if that works out for you.
The crucial changes are within the setting of the header and the method of image generation. You will be looking for these following two
header('Content-Type: image/jpeg');
change to:
header('Content-Type: image/png');
imagejpeg($im);
change to:
imagepng($im)
When dealing with png images with an alpha channel you should take a few extra steps.
Before spitting it out with imagepng(), these lines will need to be added.
imagealphablending($img, false);
imagesavealpha($img, true);
This information can be found on php.net
Edit:
Try with these alterations to this code:
if($scale < 1) {
$new_width = floor($scale * $width);
$new_height = floor($scale * $height);
$tmp_img = imagecreatetruecolor($new_width, $new_height);
imagealphablending($tmp_img,true); // add this line
//copy and resize old image to new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$img = $tmp_img;
// remove line here
}
}
header("Content-type: image/png");
imagesavealpha($img, true);
imagepng($img);
imagedestroy($img);
imagedestroy($tmp_img); // add this line here
Basically you create new layers and put these together. For each layer you will need to set the alpha blending. I was successful in creating alpha images. Let me know what your findings are .. :-) ..
I need your help
I have two images,
1. http://i.imgur.com/pyWGk.jpg (face image, type: jpeg)
2. http://i.imgur.com/LYk07.png (frame image, with hole in face, type: png)
I want insert face image into frame image
I tried this script
<?php
$image = imagecreatefromjpeg('face.jpg');
$frame = imagecreatefrompng('ironman.png');
$iw = imagesx($image);
$ih = imagesy($image);
$fw = imagesx($frame);
$fh = imagesy($frame);
imagealphablending($frame, true);
imagesavealpha($frame, true);
imagecopy($image, $frame, 0, 0, 0, 0, $fw, $fh);
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
imagedestroy($frame);
?>
The problem are:
Resolution of result image doesn't same with resolution of frame image, and
How to change position of face image, so the face image can right on hole in frame image
You can scale images to get the same resolutions. Here's the sample code for scaling:
function scale($scale){
//you can get image width and height from image info
$width = $image_width * $scale / 100;
$height = $image_height * $scale / 100;
$scaled_image = imagecreatetruecolor($width, $height);
imagecopyresampled($scaled_image, $old_image, 0, 0, 0, 0, $width, $height, $image_width, $image_height);
}
To change position of face image you can set parameters you want in imagecopy function. You'll need to set dst_x and dst_y.