PHP Crop DataURL and return DataURL - php

I'm trying to make a PHP script to crop a dataURL and return another dataURL, using GD Library, but I always get errors, how can I fix that ?
if(isset($_GET['render'])) {
if((isset($_GET['render_x'])) && (isset($_GET['render_y']))) {
if(isset($_GET['dataURL'])) {
$image = $_GET['dataURL']; // the image to crop
$image = substr($image,22);
$img = imagecreatetruecolor('200','150');
$org_img = imagecreatefromstring(base64_decode($image));
imagecopy($img,$org_img, 0, 0, 20, 20, 200, 150);
ob_start();
imagepng($img);
$image_data = ob_get_contents();
ob_end_clean ();
$image_data_base64 = base64_encode($image_data);
imagedestroy($img);
echo '<img src="data:image/png;base64,'.$image_data_base64.'" ><p>';
}
}
}
How can I fix that ? I got these errors :
Warning: imagecreatefromstring(): gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully in xxx on line 29
Warning: imagecreatefromstring(): Passed data is not in 'WBMP' format in xxx on line 29
Warning: imagecreatefromstring(): Couldn't create GD Image Stream out of Data in xxx on line 29
Warning: imagecopy() expects parameter 2 to be resource, boolean given in
and a black picture
EDIT : $_GET['dataURL'] value: data:image/png;base64,AAAFBfj42Pj4
How can I fix that ? Thanks

I think you should leave out the substr part in your code. Because the image data (type of image) is important too.
Also is the length of your url limited to an certain amount of characters per browser. So to be save keep it under 2000 characters. If that's not possible. Get the content of the image by post as #tacone suggested in his comment.
if(isset($_GET['render'])) {
if((isset($_GET['render_x'])) && (isset($_GET['render_y']))) {
if(isset($_GET['dataURL'])) {
$image = $_GET['dataURL']; // the image to crop
//$image = substr($image,22);
$img = imagecreatetruecolor('200','150');
$org_img = imagecreatefromstring(base64_decode($image));
imagecopy($img,$org_img, 0, 0, 20, 20, 200, 150);
ob_start();
imagepng($img);
$image_data = ob_get_contents();
ob_end_clean ();
$image_data_base64 = base64_encode($image_data);
imagedestroy($img);
echo '<img src="data:image/png;base64,'.$image_data_base64.'" ><p>';
}
}
}

Related

base64 encode PHP generated image without writing the image to disk

I'm generating an image in PHP for use in a users avatar.
I start by hashing the username and then doing a hexdec() conversion on various substrings of the hash to build up a set of RGB colours.
//create image
$avatarImage = imagecreate(250, 250);
// first call to imagecolorallocate sets the background colour
$background = imagecolorallocate($avatarImage, hexdec(substr($hash, 0, 2)), hexdec(substr($hash, 2, 2)), hexdec(substr($hash, 4, 2)));
//write the image to a file
$imageFile = 'image.png';
imagepng($avatarImage, $imageFile);
//load file contents and base64 encode
$imageData = base64_encode(file_get_contents($imageFile));
//build $src dataURI.
$src = 'data: ' . mime_content_type($imageFile) . ';base64,' . $imageData;
Ideally I'd not use the intermediate step and would skip writing the image out onto disk, although I'm not sure how best to implement this?
I've tried passing $avatarImage directly to base64_encode() but that expects a string so doesn't work.
Any ideas?
You can imagepng to a variable:
//create image
$avatarImage = imagecreate(250, 250);
//whatever image manipulations you do
//write the image to a variable
ob_start();
imagepng($avatarImage);
$imagePng = ob_get_contents();
ob_end_clean();
//base64 encode
$imageData = base64_encode($imagePng);
//continue
You can use output buffering to capture the image data and then use it as desired:
ob_start ( ); // Start buffering
imagepng($avatarImage); // output image
$imageData = ob_get_contents ( ); // store image data
ob_end_clean ( ); // end and clear buffer
For convenience you could create a new function to handle image encoding:
function createBase64FromImageResource($imgResource) {
ob_start ( );
imagepng($imgResource);
$imgData = ob_get_contents ( );
ob_end_clean ( );
return base64_encode($imgData);
}

Want to validate image raw data using php

I want to validate whether the image raw data is valid or not.
Below is my code :
private function __blobToImage($imagerawdata)
{
$imagedata = base64_decode($imagerawdata);
// Set the content type header - in this case image/jpeg
header('Content-Type: image/jpeg');
$path = WWW_ROOT . "commapp_images".'/';
$file = mktime().".png";
$filepath = $path.$file;
// Output the image
$image = imagecreatefromstring($imagedata);
ob_start();
imagejpeg($image, $filepath, 80);
ob_get_contents();
ob_end_clean();
return $file;
}
While using my code I'm getting the below error
"Notice (8): imagecreatefromstring() [function.imagecreatefromstring]: gd-jpeg, libjpeg: recoverable error: Premature end of JPEG file"
Any one please help me as because I strucked here with out any solution.
imagecreatefromstring already does that, it returns false on failure. So you could suppress it's message and check for the return value:
$image = #imagecreatefromstring($imagedata);
if ($image !== false)
{
...
}
Edit: You don't need the header and output buffering if you are saving to a file and you are saving a jpeg with the png extension.

php resizing image then cut it in pieces and show it, doesnt work

I'm making a website for fun but I cant seem to figure out why this piece of code wont work:
// error control
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
// loading in the image.
$img = imagecreatefromjpeg(".\image\ons\Ons-foto\mayor.jpg");
if($img != null){
$width = imagesx($img);
$heigth = imagesy($img);
$calw = 134*7;
$calh = 122*7;
$newimg = null;
if($width != null && $heigth != null){
// a check to see if the image is the right size
if($width > $calw || $width < $calh || $heigth < $calh || $heigth > $calh)
{
// here i save the resized image into the variable $newimg
imagecopyresized($newimg, $img, 0,0,0,0, $calw, $calh, $width, $heigth);
} else {
$newimg = $img;
}
$tempimg = null;
// a nested loop to automatically cut the image into pieces
for($w = 0; $w < $calw; $w+134){
for($h = 0; $h < $calh; $h+122){
// taking a piece of the image and save it into $tempimg
imagecopy($tempimg, $newimg, 0, 0, $w, $h, 134, 122);
// showing the image on screen
echo '<div class="blokken" style="margin: 1px;">';
imagejpeg($tempimg);
echo '</div>';
}
}
}
}
what I am trying to do is:
load in the image and resize it to the right size.
cut it in pieces
show it piece by piece with a little bit of space between them (i do that in a .css file hence the div tag)
these are the errors that i get:
Warning: imagecopyresized(): supplied argument is not a valid Image resource in root\ons.php on line 52
Warning: imagecopy(): supplied argument is not a valid Image resource in root\ons.php on line 63
Warning: imagejpeg(): supplied argument is not a valid Image resource in root\ons.php on line 67
Warning: imagecopy(): supplied argument is not a valid Image resource in root\ons.php on line 63
I thought that these functions might want a path to the image so I have also tried to make the image that was resized and the ones that were cut to save in this map .\image\ons\Ons-foto\ but that didn't work either. it didn't save the images nor did it load them back in to display them on the screen.
What it also could be is that imagecreatefromjpeg() doesn't output what I think it outputs and saves in $img but fopen() didn't work either and gave the same error so I cant figure it out
Could someone take a look at this and tell me why it doesn't work?
to those who do, thank you
You need to create $newimg and $tempimg before you can copy into them. All the other errors are cascading from this problem.

imagecreatefromjpeg() returns a black image when resized

I have following code
// load image and get image size
$img = imagecreatefrompng( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $imageWidth;
$new_height = 500;
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
It works fine with some images..but with certain images it shows an error like
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: gd-jpeg: JPEG library reports unrecoverable error:
Warning: imagesx() expects parameter 1 to be resource, boolean given
Warning: imagesy() expects parameter 1 to be resource, boolean given
I have also enabled
gd.jpeg_ignore_warning = 1
in php.ini
Any help appreciated.
According to a blog post from (Feb 2010) its a bug in the implementation of imagecreatefromjpeg which should return false but throws an error instead.
The solution is to check for the filetype of your image (I removed the duplicate call to imagecreatefromjpeg because its totally superfluous; we already check for right file type before and if an error occurs due to some other reason, imagecreatefromjpeg will return false correctly):
function imagecreatefromjpeg_if_correct($file_tempname) {
$file_dimensions = getimagesize($file_tempname);
$file_type = strtolower($file_dimensions['mime']);
if ($file_type == 'image/jpeg' || $file_type == 'image/pjpeg'){
$im = imagecreatefromjpeg($file_tempname);
return $im;
}
return false;
}
Then you can write your code like this:
$img = imagecreatefrompng_if_correct("{$pathToImages}{$fname}");
if ($img == false) {
// report some error
} else {
// enter all your other functions here, because everything is ok
}
Of course you can do the same for png, if you want to open a png file (like your code suggests). Actually, usually you will check which filetype your file really has and then call the correct function between the three (jpeg, png, gif).
Please see PHP Bug #39918 imagecreatefromjpeg doesn't work. The suggestion is to change the GD setting for jpeg image loading:
ini_set("gd.jpeg_ignore_warning", 1);
You then additionally need to check the return value from the imagecreatefromjpegDocs call:
$img = imagecreatefromjpeg($file);
if (!$img) {
printf("Failed to load jpeg image \"%s\".\n", $file);
die();
}
Also please see the potentially duplicate question:
the dreaded “Warning: imagecreatefromjpeg() : '/tmp/filename' is not a valid JPEG file in /phpfile.php on line xxx”
It has nearly the same error description like yours.
My solution for this issue: detect if imagecreatefromjpeg returns 'false' and in that case use imagecreatefromstring on file_get_contents instead.
Worked for me.
See code sample below:
$ind=0;
do{
if($mime == 'image/jpeg'){
$img = imagecreatefromjpeg($image_url_to_upload);
}elseif ($mime == 'image/png') {
$img = imagecreatefrompng($image_url_to_upload);
}
if ($img===false){
echo "imagecreatefromjpeg error!\n";
}
if ($img===false){
$img = imagecreatefromstring(file_get_contents($image_url_to_upload));
}
if ($img===false){
echo "imagecreatefromstring error!\n";
}
$ind++;
}while($img===false&&$ind<5);
Could you give any example of files that do / don't work?
According to http://www.php.net/manual/en/function.imagecreatefromjpeg.php#100338 blanks in remote filenamnes might cause issues.
In case you're using an URL as the source of the image, you will need to make sure the php setting allow_url_fopen is enabled.

PHP crop image from base64_decode

i am generating a screen grab jpg using html2canvas from this code. However i cant target a particaular div so i am grabbing the entire screen.
$canvasImg = $_POST['img'];
$data = base64_decode($canvasImg);
$File = "z.jpg";
$Handle = fopen($File, 'w');
fwrite($Handle, $data);
fclose($Handle);
question: how can i crop the image?
this is my attampt
$canvasImg = $_POST['img'];
$image = base64_decode($canvasImg);
$dest_image = 'z.jpg';
$img = imagecreatetruecolor('200','150');
$org_img = imagecreatefromstring($image);
$ims = getimagesize($image);
imagecopy($img,$org_img, 0, 0, 20, 20, 200, 150);
imagejpeg($img,$dest_image,90);
imagedestroy($img);
but im getting a errors
Warning: getimagesize(�PNG ) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: Invalid argument
You want imagecreatefromstring();, not imagecreatefrompng();. This'll turn it into a PHP image object, which you can then output as a JPEG using imagejpeg();
Your problem inlies that you are passing the buffer of the PNG to the function. Hence why you get the magic number of a PNG (89 50 4e 47 0d 0a 1a 0a ---OR--- 0x89 "PNG" CR LF 0x1A LF). You need to save the file to a temp location and pass the location to getimagesize and such. Hence why they complain about a stream.
You could use imagecreatefromstring(...) which will take the buffer and output a handle to the resource.
the first param of getimagesize($image); must be the image's filename.

Categories