So I'm fairly new to Symfony and I'm trying to render this custom captcha in a twig file, but the jpeg comes out in unreadable characters. When I load this up in a regular php file, the image comes out with no problem.
In an AppExtension file, I have the following,
public function getFunctions() {
return ['createImage' => new \Twig_SimpleFunction('createImage', [$this, 'createImage']),]
}
function createImage()
{
$md5_hash = md5(rand(0,999));
$captcha=substr($md5_hash, 15,5);
$_SESSION['captcha'] =$captcha;
$width = 200;
$height = 50;
$image = ImageCreate($width,$height);
$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0, 0, 0);
$green = imagecolorallocate($image, 0, 255, 0);
$brown = imagecolorallocate($image, 139, 69, 19);
$orange = imagecolorallocate($image, 204, 204, 204);
$grey = imagecolorallocate($image, 204, 204, 204);
imagefill($image, 0, 0, $black);
$font = __DIR__ . '/font.ttf';
imagettftext($image, 25, 10, 45, 45, $white, $font, $captcha);
header("Content-Type: image/jpeg");
html_entity_decode(imagejpeg($image));
imagedestroy($image);
}
and then in my twig file, I have
{{ createImage() }}
It returns characters similar to this:
�9=�����f��y{�����������#��O��w_�j�$�l|�6��[�b�-�9(\f8����_�Dž�m+�Z��sa$:u�'��l!?
imagejpg outputs the result directly to the browser so the image is being printed by php itself and not by twig, if that makes sense. In addition, the browser is trying to print it as text, but it's binary content that's why the output is mangled and why a Content-Type header is sent along, to hint the browser on what it is.
So that script is meant to be used as a standalone script in its own request.
To be used in the way you intend, and if you don't want to create a temporary file, you can capture the output and generate a img tag that can be correctly interpreted by the browser:
// Start buffering the output
ob_start();
imagettftext($image, 25, 10, 45, 45, $white, $font, $captcha);
imagejpeg($image);
imagedestroy($image);
// Get the data
$output = ob_get_clean();
// Encode in base64
$encodedImage = base64_encode($output);
// Create a img tag and inline the image
$img = "<img src='data:image/jpeg;base64, $encodedImage' />";
// Return the img tag to Twig
return $img;
Related
I trying to generate a signature from a name using the GD library, and return the png image in base64 format.
With the following code, the function correctly returns the base64 image with the signature:
<?php
function genSignature($name){
// The text to draw
$tamano = 15 * strlen($name);
$fuentes = [
'../fuentesFirma/HomemadeApple-Regular.ttf',
'../fuentesFirma/Allura-Regular.ttf',
'../fuentesFirma/DawningofaNewDay-Regular.ttf',
'../fuentesFirma/HerrVonMuellerhoff-Regular.ttf',
'../fuentesFirma/LaBelleAurore-Regular.ttf',
];
$fuente = $fuentes[array_rand($fuentes, 1)];
// Create the image
$im = imagecreatetruecolor($tamano, 60);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, $tamano, 60, $white);
// Add the text
imagettftext($im, 20, 0, 0, 30, $black, $fuente, $name);
ob_start();
imagepng($im);
$buffer = ob_get_clean();
ob_end_clean();
return base64_encode($buffer);
}
echo genSignature('María'); //Commented line when calling from another script, for testing only.
But if I include the file with the function, and call it from another script, it always returns the same image, a white square (base64). I don't understant where is the problem..
Other script:
<?php
include_once('generarFirma.php'); //in same folder
//....
//some operations...
$signature = genSignature('María');
I am trying to display a dynamically generated image from SLIM controller but I am getting a blank screen.
Thanks.
public function textToImage($request, $response, $args) {
// The text to draw
$text = "Hello World";
$length=strlen($text);
// Create the image
$im = imagecreatetruecolor($length*12, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 44, 62, 80);
$boxcolor=imagecolorallocate($im, 95, 128, 149);
$font = 'Helvetica.ttf';
imagefilledrectangle($im, 0, 0, $length*9+$capitaladjust, 29, $white);
imagettftext($im, 13, 0, 0, 20, $black, $font, $text);
$response->getBody()->write(base64_encode($im));
$response = $response->withHeader('Content-type', 'image/png');
return $response;
}
base64 encoding $im will not create a valid PNG file. Try using imgpng and then sending the raw contents of the PNG file that it creates.
The code would look something like this:
ob_start();
imagepng($im);
$data = ob_get_contents();
ob_end_clean();
$response->getBody()->write($data);
$response = $response->withHeader('Content-type', 'image/png');
return $response;
is there a way (bundle or something other) to display(convert) a text in image format.
from a text .txt input => output : display it on .png
You could use php native functions imagestring, imagettftext or even imagik (requiring you have the GD php extension activated), example with imagettftext (from the php help page) :
<?php
// Set the content-type
header('Content-type: image/png');
// Create the image
$im = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
// The text to draw
$text = 'Testing...';
// Replace path by your own font path
$font = 'arial.ttf';
// Add some shadow to the text
imagettftext($im, 20, 0, 11, 21, $grey, $font, $text);
// Add the text
imagettftext($im, 20, 0, 10, 20, $black, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
?>
First create a route for a particular Controller then add following code inside that controller
/**
* Action returns an image which is generated from
* given request text input
* #param type $text
* #return \Symfony\Component\HttpFoundation\Response
*/
public function textToImageAction($text) {
$filename = $this->saveTextAsImage($text);
$response = new Response();
// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
// Send headers before outputting anything
$response->sendHeaders();
$response->setContent(readfile($filename));
return $response;
}
/**
* Method convert given text to PNG image and returs
* file name
* #param type $text Text
* #return string File Name
*/
public function saveTextAsImage($text) {
// Create the image
$imageCreator = imagecreatetruecolor(100, 30);
// Create some colors
$white = imagecolorallocate($imageCreator, 255, 255, 255);
$grey = imagecolorallocate($imageCreator, 128, 128, 128);
$black = imagecolorallocate($imageCreator, 0, 0, 0);
imagefilledrectangle($imageCreator, 0, 0, 399, 29, $white);
$font = 'arial.ttf';
// Add some shadow to the text
imagettftext($imageCreator, 20, 0, 11, 21, $grey, $font, $text);
// Add the text
imagettftext($imageCreator, 20, 0, 10, 20, $black, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
$file_name = "upload/text_image.png";
imagepng($imageCreator, $file_name);
imagedestroy($imageCreator);
return $file_name;
}
I am trying to make a gamecard for a RSPS. This is my first time using PHP to generate text on images and when trying to apply this weird glitch happens:
But, when the original photo looks like this:
As you can see the corners are not curved like they should be. But, in the original it comes out fine. I am not talking about the location of the numbers.
Here is the code I am using:
<?php
header('Content-Type: image/png');
// Image Creation
$image_file = "SoulSplitCard.png";
$im = imagecreatefrompng($image_file);
//Colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
$rscol = imagecolorallocate($im, 23, 113, 183);
// Levels (for now)
$text = '99';
$text2 = '87';
// Font
$font = 'arial.ttf';
//Text Applications
imagettftext($im, 15, 0, 150, 35, $rscol, $font, $text);
imagettftext($im, 15, 0, 150, 81, $rscol, $font, $text2);
// Using imagepng() instead of imagejpeg()
imagepng($im);
imagedestroy($im);
?>
What is causing this to happen?
I am designing my own PHP MVC
in which any Library file can be used by following steps:
Loading the File $this->registry->load->lib('Image');
Accessing Method from the file $this->registry->Image->anyMethod();
The first line loads the file Image.php located in lib folder and returns an instance
as $this->registry->Image
then using that instance, method anyMethod() from the file can be accessed as$this->registry->Image->anyMethod(); fromController
PROBLEM is that, I am not able to Output any image !
the following code do not work if accessed from Controller but works if directly used !
codes taken from http://in2.php.net/imagettftext
public function anyMethod()
{
// Set the content-type
header('Content-Type: image/png');
// Create the image
$im = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
// The text to draw
$text = 'Testing...';
// Replace path by your own font path
$font = 'arial.ttf';
// Add some shadow to the text
imagettftext($im, 20, 0, 11, 21, $grey, $font, $text);
// Add the text
imagettftext($im, 20, 0, 10, 20, $black, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
}
Please Help , I am stuck.
Note: By adding ob_clean(); before imagepng($im); seems working but without text on the Image .
Add an exit; call after destroying the image to prevent any further output being added by your MVC system:
imagepng($im);
imagedestroy($im);
exit;
Also check there are no other Content-type headers being issued before your anyMethod() call.