PHP crop image from base64_decode - php

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.

Related

Compare string to binary photo base64encoded PHP

Im converting a photo to binary text. How come when I copy the output and the try to compare it against itself the two dont match? here is part of it
if(isset($_FILES['file'])) {
$image = $_FILES['file']['tmp_name'];
$data = fopen ($image, 'rb');
$size=filesize ($image);
$contents= fread ($data, $size);
fclose ($data);
$encoded= base64_encode($contents);
$code = "/9j/4AAQSkZJRgAB ...." //etc. the output I previously got from photo
if($code == $encoded){echo 'success';} // but they dont match
I got it. It had to do with my text editor adding a line break because the string was so long. I just deleted the space and they match.

PHP Crop DataURL and return DataURL

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>';
}
}
}

Decode image object from binary string in ImageMagick for PHP

I have a script that downloads favicons and turns them in to PNGs.
To handle the conversion, I am using ImageMagick. My current approach involves downloading the data, writing it to a file, converting the file, then deleting the originally downloaded file. Here's what I mean:
$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);
// I'd like to skip these lines
$favicon = fopen('favicon.ico', 'w');
fwrite($favicon, $image);
fclose($favicon);
$im = new Imagick();
$im->readimage('favicon.ico');
$im = $im->flattenImages();
$im->setImageFormat('png');
$im->writeImage('favicon.png');
unlink('favicon.ico');
This works, but ideally I could do it without writing the $image variable to the file favicon.ico and instead I might just convert the data within the $image variable and then $im->writeImage('favicon.png') on that.
I checked out the method getImageBlob but when I tried that I got this error:
PHP Fatal error: Uncaught exception 'ImagickException' with message 'no decode delegate for this image format `' # error/blob.c/BlobToImage/364' in /home/vagrant/test/test_image.php:73
Stack trace:
#0 /home/vagrant/test/test_image.php(73): Imagick->readimageblob('\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00 \x00h...')
#1 {main}
thrown in /home/vagrant/test/test_image.php on line 73
Any ideas?
You'll need to invoke Imagick::setFormat before reading blob.
<?php
$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);
$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
$im = $im->flattenImages();
$im->setImageFormat('PNG');
$im->writeImage('favicon.png');
Update
Flattening the .ico image may have negative effects on files containing more than one image. Simplest solution would be to iterate over all the images, and determine which sub-image to use.
$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
for( $idx = 0, $len = $im->getNumberImages(); $idx < $len; $idx++ ) {
// If this is the sub-image you want, do the following, else skip
$im->setImageFormat('png');
$im->setImageIndex($idx);
$im->writeImage(sprintf('favicon_%d.png', $idx));
}

php take image, rotate and save rotated image on server

Want to take image from own server rotate certain angle and save the image.
Image file $filename = 'kitten_rotated.jpg'; With echo '<img src='.$filename.'>'; i see the image.
Then
$original = imagecreatefromjpeg($filename);
$angle = 90.0;
$rotated = imagerotate($original, $angle, 0);
Based on this https://stackoverflow.com/a/3693075/2118559 answer trying create image file
$output = 'google.com.jpg';
If i save the same image with new file name, all works
file_put_contents( $output, file_get_contents($filename) );
But if i try to save rotated image, then file_put_contents(): supplied resource is not a valid stream resource.
file_put_contents( $output, $rotated );
Here https://stackoverflow.com/a/12185462/2118559 read $export is going to be a GD image handle. It is NOT something you can simply dump out to a file and expect to get a JPG or PNG image.. but can not understand how to use the code in that answer.
How to create image file from $rotated?
Tried to experiment, based on this http://php.net/manual/en/function.imagecreatefromstring.php
$fh = fopen( 'some_name.png' , 'w') or die("can't open file");
fwrite($fh, $data );
fclose($fh);
Does it means that need something like
$data = base64_encode($rotated);
And then write in new file?
I have not tested this, but I think you need to encode the image as base 64 first.
If you check the string from any Image URL, you'd see data:image/png;base64, preceding the hash. Prepending this to your image string and saving.
Here is a function that may help, based on what you already have:
// Function settings:
// 1) Original file
// 2) Angle to rotate
// 3) Output destination (false will output to browser)
function RotateJpg($filename = '',$angle = 0,$savename = false)
{
// Your original file
$original = imagecreatefromjpeg($filename);
// Rotate
$rotated = imagerotate($original, $angle, 0);
// If you have no destination, save to browser
if($savename == false) {
header('Content-Type: image/jpeg');
imagejpeg($rotated);
}
else
// Save to a directory with a new filename
imagejpeg($rotated,$savename);
// Standard destroy command
imagedestroy($rotated);
}
// Base image
$filename = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg';
// Destination, including document root (you may have a defined root to use)
$saveto = $_SERVER['DOCUMENT_ROOT']."/images/test.jpg";
// Apply function
RotateJpg($filename,90,$saveto);
If you want to save image just use one of GD library functions: imagepng() or imagepng().
imagerotate() returns image resource so this is not something like string.
In your case just save rotate image:
imagejpg($rotated, $output);
And now You can use $output variable as your new filename to include in view like before:
echo '<img src='.$output.'>';
Don't forget to include appropriate permissions in directory where You're saveing image.

unlink base64 encoded image not working

hi guys ive created a base64 encoded image captured with web cam now i convert the .png to .jpg all works fine but now i get two images on server both .png and .jpg how do i go about deleting the .png or is their a way to convert to jpg without saving .png image to disk thanx here my code
$rawData = $_POST['imgBase64'];
$filteredData = explode(',', $rawData);
$unencoded = base64_decode($filteredData[1]);
$randomName = rand(1000, 99999999999);
//Create the image
$fp = fopen('user/'.$randomName.'.png', 'w');
fwrite($fp, $unencoded);
//convert image from png to jpg
$image = imagecreatefrompng('user/'.$randomName.'.png');
imagejpeg($image, 'user/'.$randomName.'.jpg', 80);
unlink($fp);
ive tried it with
unlink($image);
unlink($_SERVER['DOCUMENT_ROOT'] . "/user/.$randomName.'.png'");
imagedestroy($fp);
imagedestroy($image);
Use the function unlink() but passing the file name to it instead of the file handler.
So from your example it would be:
EDIT: You might need to close the file first:
fclose( $fp );
unlink( 'user/'.$randomName.'.png' );
as far as i understand all you need is:
$data = base64_decode( $_POST['imgBase64']);
// image resource from your string
$image = imagecreatefromstring($data);
imagejpeg($image, 'user/'.$randomName.'.jpg', 80);

Categories