base64 encode PHP generated image without writing the image to disk - php

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

Related

Creating a QR Code with a centered Logo in PHP with PHP QR Code Generator

I'm creating QR codes with PHP QR Code (http://phpqrcode.sourceforge.net/). It works well but now I need a free space for a custom graphic or logo in the center of it. And I want to do this without saving the image on the server. Has anyone a suggestion? What I've got so far is this:
<?php
$param = $_GET['projectid'];
$divider = ",";
$codeText = 'Projectname'.$divider.$param;
// outputs image directly into browser, as PNG stream
//QRcode::png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)
QRcode::png($codeText, false, QR_ECLEVEL_H, 9, 2, true );
?>
Ok, I've found a solution. Where a image file is created temporaray to insert the the logo or whatever you want. I't just a very small change form the code found here http://ourcodeworld.com/articles/read/225/how-to-generate-qr-code-with-logo-easily-in-php-automatically
I'm using readfile() at the end to push everything directly to the output buffer.
<?php
// user input
$param = $_GET['projectid'];
$divider = ",";
// Path where the images will be saved
$filepath = 'content/images/qr/qr-temp-image.png';
// Image (logo) to be drawn
$logopath = 'content/images/qr/qr-freespace.png';
// we need to be sure ours script does not output anything!!!
// otherwise it will break up PNG binary!
ob_start("callback");
// text for the qr code
$codeText = 'Projectname'.$divider.$param;
// end of processing here
$debugLog = ob_get_contents();
ob_end_clean();
// create a QR code and save it in the filepath
QRcode::png($codeText, $filepath, QR_ECLEVEL_H, 9, 2, true );
// Start DRAWING LOGO IN QRCODE
$QR = imagecreatefrompng($filepath);
// START TO DRAW THE IMAGE ON THE QR CODE
$logo = imagecreatefromstring(file_get_contents($logopath));
$QR_width = imagesx($QR);
$QR_height = imagesy($QR);
$logo_width = imagesx($logo);
$logo_height = imagesy($logo);
// Scale logo to fit in the QR Code
$logo_qr_width = $QR_width/3;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;
imagecopyresampled($QR, $logo, $QR_width/3, $QR_height/3, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
// Save QR code again, but with logo on it
imagepng($QR,$filepath);
// outputs image directly into browser, as PNG stream
readfile($filepath);
?>
There's a much better/modern library now available: https://github.com/chillerlan/php-qrcode
There is also an example for including space for a logo:
https://github.com/chillerlan/php-qrcode/blob/d650fe73067c2559519f09949e9b71b466ab2bee/examples/imageWithLogo.php

Imagecreatefromwebp(): WebP decode: fail to decode input data

I am trying to convert a webp file to JPEG using imagecreatefromwebp() but unfortunately, it throws me a warning: Warning: imagecreatefromwebp(): WebP decode: fail to decode input data.
Here's my code
$filename = dirname(__FILE__)."\\".$keyword."1.webp"; // $keyword = 'xyz';
$im = imagecreatefromwebp($filename);
// Convert it to a jpeg file with 100% quality
imagejpeg($im, './example.jpeg', 100);
imagedestroy($im);
Please help.
i am using this code, it works fine for me. Here $data contains the base64encoded data
$im = imagecreatefromwebp($data);
$imageResult = imagejpeg($im, $destinationPath . $fileName, 100);
imagedestroy($im);
The imagecreatefromwebp() function accepts either a valid file or URL. You can also pass the your binary data in that function. You can check the function definition and example here http://php.net/manual/en/function.imagecreatefromwebp.php

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.

How to send base64 png image to PHP

I have a base64 png image.
I'd like to use it in FPDF
I create it like this:
var dataURI = canvas.toDataURL("image/png");
And send it to FPDF like this:
$('#send').click(function(e){
e.preventDefault();
var uri = "create_pdf.php?imgURI="+ dataURI;
window.open ( uri, "Temp wind" );
});
inside the create_pdf.php I have:
require('fpdf.php');
$img = $_GET['imgURI'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$pdf = new FPDF();
$pdf->AddPage();
$pdf->Image( $data, 0, 0, 200 );
$pdf->Output( "myimage.pdf", 'D' );
Instead of the usual prompt to save PDF I get this error:
Image file has no extension and no type was specified: �PNG IHDRSJ����IDATx......
How to properly send that base64 encoded image?
Seems like pfdf takes saved iamge as parameter, not base64
Try the answer here
FPDF image() function checks for the file type based on the $file string which should contain a filepath. If you offer a type eg 'png' in the optional parameters you can overcome this part.
Afterwards, FPDF will try to fopen $file within its _parsepng and _parsejpg functions so you can easily take use of the data wrapper
http://www.php.net/manual/en/wrappers.data.php
$fpdf->Image('data://image/png;base64,'.$image_data,null, null, 0, 0, 'png');

php : How to create a string of image binary without saving it to a file?

I have an image variable,
$im = imagecreatetruecolor(400, 300);
Is there anyway to get a string of binary of this image in jpeg format without saving it to a file?
Thanks!
Yes, this is possible (even without output buffering). It's undocumented as it seems, but you can pass a stream resource instead of a file name.
<?php
$stream = fopen("php://memory", "w+");
$i = imagecreatetruecolor(200, 200);
imagepng($i, $stream);
rewind($stream);
$png = stream_get_contents($stream);
ob_start();
imagejpeg($im);
$imageString = ob_get_clean();
As a function and adding imagedestroy().
function imagejpeg_tostring($im,$quality=75) {
ob_start(); //Stdout --> buffer
imagejpeg($im,NULL,$quality); // output ...
$imgString = ob_get_contents(); //store stdout in $imgString
ob_end_clean(); //clear buffer
imagedestroy($im); //destroy img
return $imgString;
}

Categories