PHP gd library displsys black screen with white box instead of image - php

I am pretty new to PHP and currently using XAMPP. I wanted to create a captcha image using the gd library but then I noticed that all I got was a black screen with a little white box outline at the middle. This is the output in spite of any code used. I have tried different code samples from different websites to no avail. I have confirmed that the gd library has been enabled. I have uninstalled and reinstalled xampp. I have also searched related questions but none of the suggested solutions works for me.
here is my code
session_start();
// Set some important CAPTCHA constants
define('CAPTCHA_NUMCHARS', 6); // number of characters in pass-phrase
define('CAPTCHA_WIDTH', 100); // width of image
define('CAPTCHA_HEIGHT', 25); // height of image
// Generate the random pass-phrase
$pass_phrase = "";
for ($i = 0; $i < CAPTCHA_NUMCHARS; $i++) {
$pass_phrase .= chr(rand(97, 122));
}
// Store the encrypted pass-phrase in a session variable
$_SESSION['pass_phrase'] = SHA1($pass_phrase);
// Create the image
$img = imagecreatetruecolor(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
$bg_color = imagecolorallocate($img, 255, 255, 255); // white
$text_color = imagecolorallocate($img, 0, 0, 0); // black
$graphic_color = imagecolorallocate($img, 64, 64, 64); // dark gray
// Fill the background
imagefilledrectangle($img, 0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, $bg_color);
// Draw some random lines
for ($i = 0; $i < 5; $i++) {
imageline($img, 0, rand() % CAPTCHA_HEIGHT, CAPTCHA_WIDTH, rand() %
CAPTCHA_HEIGHT,
$graphic_color);
}
// Sprinkle in some random dots
for ($i = 0; $i < 50; $i++) {
imagesetpixel($img, rand() % CAPTCHA_WIDTH, rand() % CAPTCHA_HEIGHT,
$graphic_color);
}
// Draw the pass-phrase string
imagettftext($img, 18, 0, 5, CAPTCHA_HEIGHT - 5, $text_color, 'Courier New Bold.ttf', $pass_phrase);
// Output the image as a PNG using a header
header("Content-type: image/png");
imagepng($img);
// Clean up
imagedestroy($img);
?>
Edit:
I have been able to pinpoint the problem to the header(Content-type) line.
Still haven't figured the solution yet.

After hours of scouring different forums. I have come to understand the problem better. The problem is not with gd library but rather the header(Content-type) line
When I decide to create an image file rather than sending the image through a header. The correctly displays.
Once I figured that out, finding the solution became easier as now I am looking for the solution in the right place.
The problem is that my PHP script is emitting a UTF-8 byte order mark (EF BB BF) before outputting the PNG image content.
The solution that worked for me was to place ob_clean() before header line.
For more explanation see the link below.
https://stackoverflow.com/a/22565248/10349485
I used and pieced together different solutions from different forums to better understand and to arrive at this solution but the link above was my final destination.
I am not deleting the question even though there are other similar questions because of the amount of trouble it took me to get and understand this problem, also because the answers there didn't work for me. Hopefully, this helps someone in the future avoid the trouble I went through.

from many days i'm also face this problem but this solution work for me
use __DIR__ with your font file path like that
`$font_path = __DIR__ .'/font.ttf';`

Related

Create dynamic name avatar/icon like Google

I want to create a logo or profile avatar from first letters of name, like Google. Is there any method or service to do it?
I am tried to learn the code about make image with php but it's to hard. One time I found a website about this dynamic image text but I don't find.
Most easy examples you will find online are going to use PHP's imagecreate and imagestring functions, such as this one:
https://phppot.com/php/how-to-convert-text-to-image-using-php/
Here is a quick example-code I've put together based on the above link, that creates an image similar to the Google avatars:
$img = imagecreate(250, 250);
$textbgcolor = imagecolorallocate($img, 52, 152, 219);
$textcolor = imagecolorallocate($img, 255, 255, 255);
$txt = "AB";
$fontfile = "/arial.ttf";
imagettftext($img, 100, 0, 35, 170, $textcolor , $fontfile, $txt);
ob_start();
imagepng($img);
printf('<img src="data:image/png;base64,%s"/ width="100">', base64_encode(ob_get_clean()));
You will need place the arial.ttf fontfile in the same directory as your PHP file for this to work.
However, in most fonts that are aesthetically pleasing, letters do not have the same width. So you will find it difficult to center the text, since you can't use the same X value for the anagram "MM" and "II". I would advise you to use a library that has extended functions like aligning text to the middle, and my bet would be on gd-text.

Unicode font broken when merge images & text using php

I tried to merge text with images, but my text not rendering correctly after merge.
See my screenshot:
The Red mark ( আমি তোমায় ভালবাসি ) text format is correct while I normally show the variable. Font Link: http://www.fonts2u.com/solaimanlipi.font
But while I merge text with image, its broken or not render correctly.
Here is my full code:
<?php
mb_language('uni');
mb_internal_encoding('UTF-8');
$username="";
if(isset($_POST['user'])){
$username = $_POST['user'];
$username = mb_convert_encoding($username, 'HTML-ENTITIES',"UTF-8");
$username = html_entity_decode($username,ENT_NOQUOTES, "ISO-8859-1");
}
$im = imagecreatefromjpeg('image.jpg');
//The numbers are the RGB values of the color you want to use
$black = ImageColorAllocate($im, 255, 255, 255);
//The canvas's (0,0) position is the upper left corner
//So this is how far down and to the right the text should start
$start_x = 50;
$start_y = 80;
$font = 'SolaimanLipi.ttf';
Imagettftext($im, 50, 0, $start_x, $start_y, $black, $font, "$username");
//Creates the jpeg image and sends it to the browser
//100 is the jpeg quality percentage
Imagejpeg($im, 'result.jpg', 100);
echo "<div style='color:red;font-size:60px;'>".$username."</font><br /><img src='result.jpg' height='500' />"
?>
Note 1: SolaimanLipi.ttf is Bangla (Unicode) Font.
Note 2: Bangla (Unicode) font not rendering correctly in tcpdf This Stack & Stack solution will help you to understand my problem & give me a solution.
Please someone help me to get out this problem. Thanks in advance.
[[Previously I asked the same question and no one answer. So I re-post this and deleted the old one. I hope this time someone help me.]]
Bengali is one of a number of scripts that cannot be rendered simply by putting one character after the next. The shapes of characters change and merge depending on their neighbours.
To render this correctly, you need a set of features known as Complex Text Layout. On text rendering systems that do not support CTL, you'll get the equivalent of each letter being rendered alone, so আমি comes out like আ ম ি.
The GD library used by PHP's imagettftext function does not support Complex Text Layout. You'd have to use some higher-level rendering library such as Pango. This is a bit of a pain; if you can achieve your aims by rendering the text over the image as part of HTML/CSS/SVG that would certainly be easier.
(BTW writing $username out to the HTML without doing htmlspecialchars() is an XSS security hole, and writing-then-serving the JPEG file is unsafe as it will break if two requests come in at the same time. You should also serve your page/form as UTF-8 by adding <meta charset="utf-8"/> so you don't have to do the crazy dance with mb_convert_encoding/html_entity_decode).

PHP GD and transparent images sometimes work

While reading up on the issues merging transparent images in PHP, it seems that everyone is in the "it works" or "it doesn't work" camps. I have found a way to demonstrate each case.
I wish to take a PNG, cut an ALPHA hole in it and then merge it on top of another image. In this case, I cut a hole in an image from google maps, and paste it over a red block. I have two images from google maps. One is of Manhattan and one is of my house. One works, and one does not. The only difference is one was "saved" via a browser.
If you run the code below, you will see the difference in outputs. Does anyone know why the same code would treat two PNG files completely differently? It must be the difference in the PNG files themselves, but then what would it be?
<?php
sometimesworks("https://maps.googleapis.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=12&size=400x400&maptype=hybrid", "google");
sometimesworks("https://lh4.googleusercontent.com/UQvV_dpBa3_rVf25pvLXKD3OwzF4FtPnHBHkzdWqjCQ5mlFqcFfId9echIgDMv_xYRRYzLaKEXphw7g=w2447-h1106", "myhouse");
function sometimesworks($p_image, $p_prefix)
{
$image_top =imagecreatefrompng($p_image);
$brush = imagecolorallocate($image_top, 0, 0, 0); //create a black brush
imagefilledpolygon($image_top, explode(",", "10,10, 120,22, 80,280, 200, 191"), 4, $brush); //fill a polygon
imagecolortransparent($image_top, $brush); //turn the black to be transparent
imagepng($image_top, './'.$p_prefix.'.transparent.png'); //save the file to confirm that it is working.
//create a big red square
$image_bottom = imagecreatetruecolor(imagesx($image_top), imagesy($image_top));
$red = imagecolorallocate($image_bottom, 255, 0, 0);
imagefill($image_bottom, 0, 0, $red);
imagepng($image_bottom, './'.$p_prefix.'.red.png');
//merge the top onto the bottom.
$out = imagecreatetruecolor(imagesx($image_top), imagesy($image_top));
imagecopy($out, $image_bottom, 0, 0, 0, 0, imagesx($image_top), imagesy($image_top));
imagecopy($out, $image_top, 0, 0, 0, 0, imagesx($image_top), imagesy($image_top));
imagepng($out, './'.$p_prefix.'.out.png');
}
The issue with the above code is that the PNG files were of different type. One was a truecolor image and the other was a palette. The code to merge files differs depending on what is being done.
This is a good reference for the merging of "palette" based PNG files with transparency.

Captcha image not loading?

How do I get this to load? Right now, it's not showing any image at all... I'm not really that great at creating captcha's because I usually never do this.
captcha.php:
<?php
$string = '';
for ($i = 0; $i < 5; $i++) {
// this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122));
}
$image = imagecreatetruecolor(170, 60);
$color = imagecolorallocate($image, 200, 100, 90); // red
$white = imagecolorallocate($image, 255, 255, 255);
imagefilledrectangle($image,0,0,399,99,$white);
imagettftext ($image, 30, 0, 10, 40, $color, ASSETPATH."arial.ttf", $string);
header("Content-type: image/png");
imagepng($image);
?>
register.php:
<?php echo '<img src="'.ASSETPATH.'img/captcha.php" />'; ?>
My asset path IS correct because I'm using it elsewhere and it loads perfectly fine. Is the MVC format of this project messing it up somehow??
How about using one of the captcha services like recaptcha?
Judging by your use of this constant ASSETPATH both for you image URI as well as the fontfile path in imagettftext I can only assume you have your fontfile stored in the same path as that of your image?
If this is not the case, or the file could not be opened there, PHP will throw a Warning of imagettftext(): Invalid font filename. If display_errors is set to On in your php.ini (you can check phpinfo to verify this) this means the error message will be sent to the output stream along with your image data (i.e. corrupting the image data and cause your browser not to display the image). This would also prevent the headers from being modify since the error would have occurred before your call to header.
However, if display_errors is not turned on and PHP could not find the fontfile you supplied or it could not be open for any reason (e.g. permissions) the result will be a blank 170x60 PNG image.
If I test your code locally it proves to work as expected, as long as I supply PHP with the correct absolute path to my truetype font file.
For example, I have some truetype fonts on my system stored at /usr/share/fonts/truetype/, which is definitely not in my webroot as I don't normally keep my font files there. Note, also, that my PHP user has sufficient permissions to read from this path.
Now, if I supply PHP with the correct absolute path to the truetype font file that I would like to use I get the following image using your code...
$string = '';
for ($i = 0; $i < 5; $i++) {
// this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122));
}
$image = imagecreatetruecolor(170, 60);
$color = imagecolorallocate($image, 200, 100, 90); // red
$white = imagecolorallocate($image, 255, 255, 255);
imagefilledrectangle($image,0,0,399,99,$white);
imagettftext ($image, 30, 0, 10, 40, $color, '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-ExtraLight.ttf', $string);
header("Content-type: image/png");
imagepng($image);
What you should try to do in order to debug this further is run the PHP script that generates the image by itself, with display_errors turned on and error_reporting set to -1 and if it is indeed the case that your font file is the problem you will see this in your error_log or in the error output displayed during testing that script with display_errors on.

PHP Dynamic Image Has Undesired Border

I'm having some problems with a project I'm doing using Google Maps.
I have the map functionality all figured out, and it works great. I want to add dynamically generated icons to the map, and I've figured out how to do that as well using PHP to dynamically add the text I want to the icon image.
However, the icon is changed beyond the text I want added. The border around the original is made much thicker when there is nothing in the PHP code that should be doing anything like that. The image I've attached to this post shows the two icons. The top icon is the original, and the bottom one has the text added to it by my PHP script. Notice the thicker border.
Here's my PHP code:
<?php
// GETS THE NUMBER TO ADD TO THE ICON
$number = $_GET['number'];
// THE SOURCE OF THE ICON THAT I WANT TO ADD THE TEXT TO
$src = $_GET['src'];
header ("Content-type: image/png");
$font = 4;
$im = imagecreatefrompng($src);
// POSITION THE TEXT TO THE PREFERRED LOCATION
$x = 5 ;
$y = 2;
$textColor = imagecolorallocate ($im, 0, 0,0);
imagestring ($im, $font, $x, $y, $number, $textColor);
imagepng($im);
?>
Keep in mind that all of this is working, except the image is changed beyond just adding the text. The icons look much nicer without the really thick border.
I don't know for sure if this is the case but something like this can be caused if your initial image used transparency at the margin to get an effect of rounded corners. if you want to keep the transparency from the initial image you need to research other functions also. something like this should help:
imagealphablending( $im, false );
imagesavealpha( $im, true );
*right after imagecreatefrompng

Categories