I'm trying to tile multiple images, i.e. put one directly underneath another. They all have the same width (120px) and differing heights.
This is what I have:
$finalbg = null;
for($i=0; $i<7; $i++) {
$addbg = imagecreatefromjpeg('images/left/'.$url[$drawn]);
$addsize = imagesy($addbg);
if($finalbg != null) $basesize = imagesy($finalbg); else $basesize = 0;
$newsize = $addsize+$basesize;
$newbg = imagecreatetruecolor(120, $newsize);
if($finalbg != null) imagecopy($newbg, $finalbg, 0, 0, 0, 0, 120, $basesize);
imagecopy($newbg, $addbg, 0, $basesize, 0, 0, 120, $addsize);
$finalbg = $newbg;
}
header( "Content-type: image/jpeg" );
imagejpeg($finalbg);
The sizes are outputting correctly, but it keeps telling the image contains errors, and I have no idea why :( Same thing if I try to output addbg or newbg.
Thanks.
Okay, apparently the problem was that there was HTML on the page that was supposed to be rendered, which turns out not to be possible in combination with a GD image.
So I took a different approach. I saved the rendered image as a file, like so:
imagejpeg($finalbg, 'images/left/bg.jpg');
and set it as the background in CSS. And now it works!
Related
I've a script I use to convert JPEGs or PNGs to PNGs for database storage, I encode the file into base64 and store it in a database, I pull the file from the database or cache and when displaying it on a website I just pull the image data from the database or cache and do a base64 decode on it and display it using a standard IMG tag.
The issue I'm having is, no matter if the background is transparent or what colour I create as the image's background it always shows up as black when being displayed on the webpage.
I've tried numerous of the questions on the right side and none of the answers seems to work for me.
Encode Function
public function encode($image, $resize = false, $dirLevel = '')
{
$vTempFileName = TEMP_DIR . '_'.rand(1111111, 9999999) . '.png';
// Convert image to PNG
$image = imagecreatefromstring(file_get_contents($image));
imagealphablending($image, true);
imagepng($image, $vTempFileName);
$vImageDetails = array(base64_encode(file_get_contents($vTempFileName)), filesize($vTempFileName));
// Remove temporary file after processing
#unlink($vTempFileName);
return $vImageDetails;
}
Decode Function
echo base64_decode($image);
I've also tried using the below two functions
To save transparency you need to add imagesavealpha See http://php.net/manual/en/function.imagesavealpha.php
public function encode($image, $resize = false, $dirLevel = '')
{
$vTempFileName = TEMP_DIR . '_'.rand(1111111, 9999999) . '.png';
// Convert image to PNG
$image = imagecreatefromstring(file_get_contents($image));
imagealphablending($image, true);
imagesavealpha($image, true);
imagepng($image, $vTempFileName);
$vImageDetails = array(base64_encode(file_get_contents($vTempFileName)), filesize($vTempFileName));
// Remove temporary file after processing
#unlink($vTempFileName);
return $vImageDetails;
}
imagefill will perform a flood fill on the selected coordinates with the desired color defined as $transparent See: http://php.net/manual/en/function.imagefill.php
$fillColor = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $fillColor);
To flood fill the adjoining color at the top left of the image with the desired fillColor.
Otherwise to add transparency use imagecolortransparent see http://php.net/manual/en/function.imagecolortransparent.php
$replaceBlack = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image, $replaceBlack);
to replace the color black as transparent.
This may or may not help you but... you really don't want to store images into a database if you can avoid it. Is there a good reason you are doing this? File systems are good at storing binary files. Databases are good at storing data. Use the appropriate tool for the job – store it as a file.
I've tried everything i know for the last 3 days, but can't figure it out, so i hope someone could help me on this one.
I want to get multiple records from a database. In the database is for every single record the link to a thumbnail, x-coordinate and an y-coordinate specified.
The image (a map of a building) must be created starting with an empty map of a building (plattegrond.jpg). Then, multiple thumbnails must be added which contains numbers (see image below) on the coordinated specified in the database. When all the thumbnails are added, it must be saved as something like Project1.jpg or whatever.
$emptymap = "plattegrond.jpg"; // this is a map of a building
$newmap = "Project1.jpg"; // this must be the new map with the images
header('Content-type: image/jpeg');
$im = #imagecreatefromjpeg('maps/'.$emptymap) or die("Cannot Initialize new GD image stream");
$im2 = #imagecreatefromjpeg('thumbnails/'.$linkToThumbnail);
imagecopy($im, $im2, $xcoord, $ycoord, 0, 0, imagesx($im2), imagesy($im2));
imagejpeg($im, 'maps/'.$newmap, 100);
imagedestroy($im);
imagedestroy($im2);
The thumbnails already exists and are all small images saved as 1.jpg, 2.jpg, 3.jpg, etc.
So, in summary:
How do i put multiple images with coordinates, which are specified in a database , on that single image?
All suggestions are welcome!
This is a preview of a map with a single thumbnail:
With the help of Darren his link, i managed to figure it out, finaly! I can sleep again :)
<?php
$coords = array
(
array("2","100","200"),
array("3","200","100"),
array("4","250","30"),
array("5","134","90")
);
$arrlength = count($coords);
$map = "Project2.jpg";
for($x = 0; $x < $arrlength; $x++) {
addThumb($map, $coords[$x][0], $coords[$x][1], $coords[$x][2]);
}
function addThumb($map, $thumb, $xcoord, $ycoord)
{
$thumb .= ".jpg";
$imMap = imagecreatefromjpeg('maps/'.$map);
$imThumb = imagecreatefromjpeg('thumbnails/'.$thumb);
imagecopy($imMap, $imThumb, $xcoord, $ycoord, 0, 0, imagesx($imThumb), imagesy($imThumb));
imagejpeg($imMap, 'maps/'.$map, 100);
imagedestroy($imMap);
imagedestroy($imThumb);
}
?>
I have the following PHP code...
$destination_image_x = "235";
$destination_image_y = "230";
$destination_image = imagecreatetruecolor($destination_image_x, $destination_image_y);
$source_image_x = imagesx($temp_profile_picture_converted);
$source_image_y = imagesy($temp_profile_picture_converted);
$temp_profile_picture_converted = imagecopyresampled($destination_image, $temp_profile_picture_converted, 0, 0, 0, 0, $destination_image_x, $destination_image_y, $source_image_x, $source_image_y);
imagejpeg($temp_profile_picture_converted, $user_profile_picture_filename,'75');
imagedestroy($temp_profile_picture_converted);
The function of this code is to scale an image passed to it, and save it at a specified directory. I'm able to save the image using "imagejpeg" normally if I ommit the resizing snippet. The variable "$temp_profile_picture_converted" is assigned to a jpg image I created from the user's uploaded image with "imagecreatefromjpeg." (Or imagecreatefrompng, or imagecreatefromgif, etc.)
You are using the same variable $temp_profile_picture_converted twice in the following line. The function imagecopyresampled() returns a boolean and is overwriting the image this variable holds. The return value from this function is only to check success. Change it to:
if (! imagecopyresampled($destination_image, $temp_profile_picture_converted, 0, 0, 0, 0, $destination_image_x, $destination_image_y, $source_image_x, $source_image_y)){
// then give error message...
}
UPDATE
However, you have other errors. You need to change the first parameter of imagejpeg(). I also changed the size vars from strings to numbers - not sure if it mattered.
imagejpeg($destination_image, $user_profile_picture_filename,75);
I successfully ran the following code
$destination_image_x = 235;
$destination_image_y = 230;
$source_image_x = imagesx($temp_profile_picture_converted);
$source_image_y = imagesy($temp_profile_picture_converted);
$destination_image = imagecreatetruecolor($destination_image_x, $destination_image_y);
imagecopyresampled($destination_image, $temp_profile_picture_converted, 0, 0, 0, 0, $destination_image_x, $destination_image_y, $source_image_x, $source_image_y);
imagejpeg($destination_image, $user_profile_picture_filename,75);
imagedestroy($temp_profile_picture_converted);
imagedestroy($destination_image);
Note that I also added the last statement imagedestroy($destination_image);
I have removed my original question as I have managed to partially get this working, what I have is 7 images,
https://dl.dropboxusercontent.com/u/58586640/layer1.png
https://dl.dropboxusercontent.com/u/58586640/layer2.png
https://dl.dropboxusercontent.com/u/58586640/layer3.png
https://dl.dropboxusercontent.com/u/58586640/layer4.png
https://dl.dropboxusercontent.com/u/58586640/layer5.png
https://dl.dropboxusercontent.com/u/58586640/layer6.png
https://dl.dropboxusercontent.com/u/58586640/layer7.png
Each of these images when placed over the top of each other should create one image that slots together perfectly.
The current result i have is,
https://dl.dropboxusercontent.com/u/58586640/Screen%20Shot%202013-12-11%20at%2018.31.57.png
As you can see it works nearly perfectly but 2 of the layers are either not being copied or are not getting the alphas saved correctly. I am not sure what I am doing wrong, as all the other layers seem to working fine, the images that are coming in as black are,
https://dl.dropboxusercontent.com/u/58586640/layer3.png https://dl.dropboxusercontent.com/u/58586640/layer4.png
Here is my current code,
<?php
$images = array('img/layer1.png', 'img/layer2.png', 'img/layer3.png', 'img/layer4.png', 'img/layer5.png', 'img/layer6.png', 'img/layer7.png');
// foreach($images as $i) {
// var_dump(file_exists($i));
// }
// Allocate new image
$img = imagecreatetruecolor(704, 469);
// Make alpha channels work
imagealphablending($img, true);
imagesavealpha($img, true);
foreach($images as $fn) {
// Load image
$cur = imagecreatefrompng($fn);
imagealphablending($cur, true);
imagesavealpha($cur, true);
// Copy over image
imagecopy($img, $cur, 0,0,0,0, 704, 469);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png');
imagepng($img);
As you can see I have checked to make sure that the files exist, and they do so it must be GD problem, anyone have ideas?
Funny I did exactly this yesterday here's how I did it using a static background layer and a QR code which is generated prior to the combine.
$template = imagecreatefrompng("./images/asset_barcode_template.png");
//QR created fine assemble final image
$qrimage = imagecreatefrompng($this->qrfilename);
//final image assembled just fine
imagecopy($template, $qrimage, 230, 6, 0, 0, 106, 106);
imagepng($template,$filename,0,PNG_NO_FILTER);
I am trying to take a rectangular png and add depth using GD by duplicating the background and moving it down 1 pixel and right 1 pixel. I am trying to preserve a transparent background as well.
I am having a bunch of trouble with preserving the transparency.
Any help would be greatly appreciated.
Thanks!
$obj = imagecreatefrompng('rectangle.png');
$depth = 5;
$obj_width = imagesx($obj);
$obj_height = imagesy($obj);
imagesavealpha($obj, true);
for($i=1;$i<=$depth;$i++){
$layer = imagecreatefrompng('rectangle.png');
imagealphablending( $layer, false );
imagesavealpha($layer, true);
$new_obj = imagecreatetruecolor($obj_width+$i,$obj_height+$i);
$new_obj_width = imagesx($new_obj);
$new_obj_height = imagesy($new_obj);
imagealphablending( $new_obj, false );
imagesavealpha($new_obj, true);
$trans_color = imagecolorallocatealpha($new_obj, 0, 0, 0, 127);
imagefill($new_obj, 0, 0, $trans_color);
imagecopyresampled($new_obj, $layer, $i, $i, 0, 0, $obj_width, $obj_height, $obj_width, $obj_height);
//imagesavealpha($new_obj, true);
//imagesavealpha($obj, true);
}
header ("Content-type: image/png");
imagepng($new_obj);
imagedestroy($new_obj);
The solution to virtually any related problem with PHP GD is using this small utility:
http://phpimageworkshop.com/
It´s a PHP Class based on GD... but it´s has two "insignificant" differences:
Extremely easy
Always get the work done
Two days ago I have a similar problem (Join multiple PNG Images into a single one PNG using PHP) but this Library saves the day!