PHP 5: how to write utf-8 binary data - image - to output? - php

I have a Ubuntu server and PHP5, and the PHP script files, and all output are in UTF-8.
I'm trying to send an image to the output stream, but just garbled chinese characters shows up in the output:
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
header('Content-type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
any suggestions?

Your code works perfectly fine on my machine :
<?php
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
header('Content-type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
die;
?>
Are you sure you are not outputing anything before or after that code ? Even any kind of whitespace would be a source of troubles.
Or maybe your script is doing something else somewhere ?
If it still doesn't work, maybe trying with imagettftext, to use a "better" / more complete font than the ones used by imagestring might help ?
Using something like this, for instance :
$font = '/usr/share/fonts/truetype/msttcorefonts/arial.ttf';
imagettftext($im, 20, 0, 10, 20, $text_color, $font, 'A Simple éléphant String');
BTW, did you try without those line :
header('Content-type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
If there is an error/warning/notice, removing those lines might help you seeing those.
And, as a sidenote : using JPEG for images that contain some text generally doesn't give great results, as JPEG is a destructive compression mechanism. Using PNG, in that kind of situation, might get you better results ;-)

Try removing the UTF-8 byte order mark, because it gets prepended to the contents of your JPEG image, rendering it invalid.

Related

Using GD on PHP does not work - only black square

I'm trying to draw a simple image with GD on PHP 7.2.5 on my Server (Debian 4.9.88-1+deb9u1).
My source code looks simply like that:
<?php
error_reporting(E_ALL);
header("Content-type: image/png");
$string = $_GET['text'];
$im = imagecreatefromjpeg("test.jpg");
$orange = imagecolorallocate($im, 220, 210, 60);
$px = (imagesx($im) - 7.5 * strlen($string)) / 2;
imagestring($im, 3, $px, 9, $string, $orange);
imagepng($im);
imagedestroy($im);
?>
test.jpg is available in the same folder.
PHP-Version: 7.2.5
I can't see anything related in the log files.
GD is activated on the server:
Result looks like that:
Result of the previous shown source code
Problem solved by following this answer:
header('Content-Type: image/png'); not working anymore?
The problem was that my .php file was not in ANSI but in UTF-8, after converting it to ANSI it worked.

PHP imagettftext() - nothing is displaying

Trying to display a font using the GD library. There is indeed an image there, it's just that theres nothing displaying.
PHP:
header('Content-Type: image/png');
$font = $_GET['font'];
// Create the image
$image = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($image, 255, 255, 255);
$grey = imagecolorallocate($image, 128, 128, 128);
$black = imagecolorallocate($image, 0, 0, 0);
imagefilledrectangle($image, 0, 0, 399, 29, $white);
// The text to draw
$text = 'The Quick Brown Fox Jumps over the Lazy Dog';
$font = '/Aller/' . $font;
// Add the text
imagettftext($image, 20, 0, 10, 20, $black, $font, $text);
imagepng($image);
HTML:
<img src="fontgen.php?font=Aller_Rg.ttf" alt="" />
The font resides in fonts/Aller/Aller_Rg.tff
What am I doing wrong?
The problem seems to be the $font variable. From the documentation:
Depending on which version of the GD library PHP is using, when fontfile does not begin with a leading / then .ttf will be appended to the filename and the library will attempt to search for that filename along a library-defined font path.
When using versions of the GD library lower than 2.0.18, a space character, rather than a semicolon, was used as the 'path separator' for different font files. Unintentional use of this feature will result in the warning message: Warning: Could not find/open font. For these affected versions, the only solution is moving the font to a path which does not contain spaces.
In many cases where a font resides in the same directory as the script using it the following trick will alleviate any include problems.
<?php
// Set the enviroment variable for GD
putenv('GDFONTPATH=' . realpath('.'));
// Name the font to be used (note the lack of the .ttf extension)
$font = 'SomeFont';
?>
You also said that the font resides in fonts/Aller/ directory. Whereas, in your script, there is no reference to the fonts directory.
The code is all correct except this part
$font = '/Aller/' . $font;
It tries the absolute path '/Aller/Aller_Rg.tff' not 'Aller/Aller_Rg.tff'
Changing it to $font = 'Aller/' . $font; should work.
Also you should check the error log, it should mention Invalid font filename
When in doubt remove header('Content-Type: image/png'); for debugging.

Include PHP code in html error

Am working with an small php project . in creating an text generating image. took some sample codes and tired.
<?php
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
header('Content-Type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
?>
i made some changes and it works good . when i tried to insert this php file in other html file using it results broken image. how can i solve this why it happens.
Please make sure that you don't have any whitespace before your <?php statment. In your example above there are 4 spaced before the <?php. Note that this also is important for empty lines.
You can't have the same page being both HTML and an image. The way you do what you want is by having the HTML file contain an IMG tag that references this script.
<img src="yourscript.php">
An HTML file cannot have multiple header sections. Once you have rendered content on the page the call to header() will generate an error.

PHP script to render a single transparent pixel (PNG or GIF)

I have to create a PHP that will return an image stream of one transparent dot (PNG or GIF)
Could you point me to an easy to use solution?
Transparent 1x1 PNG:
header('Content-Type: image/png');
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');
Transparent 1x1 GIF:
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');
In PHP 5.4 and higher it is possible to use hex2bin, which is roughly two times faster than base64_decode (tested with the blank GIF file below). The code to output images would be:
Transparent 1x1 PNG:
header('Content-Type: image/png');
die(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'));
Transparent 1x1 GIF:
header('Content-Type: image/gif');
die(hex2bin('47494638396101000100900000ff000000000021f90405100000002c00000000010001000002020401003b'));
You can easily convert base64 encoded data into hexadecimal:
echo bin2hex(base64_decode($data));
Or a file:
echo bin2hex(base64_decode(file_get_contents($filename)));
However, using the native PHP escape method suggested by #Lukas Liesis is the fastest, about 12.5 times faster than base64_decode, according to my benchmark. And it would work with virtually any version of PHP. Here are the code snippets:
Transparent 1x1 PNG:
header('Content-Type: image/png');
die("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x01\x03\x00\x00\x00\x25\xdb\x56\xca\x00\x00\x00\x03\x50\x4c\x54\x45\x00\x00\x00\xa7\x7a\x3d\xda\x00\x00\x00\x01\x74\x52\x4e\x53\x00\x40\xe6\xd8\x66\x00\x00\x00\x0a\x49\x44\x41\x54\x08\xd7\x63\x60\x00\x00\x00\x02\x00\x01\xe2\x21\xbc\x33\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82");
Transparent 1x1 GIF:
header('Content-Type: image/gif');
die("\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x90\x00\x00\xff\x00\x00\x00\x00\x00\x21\xf9\x04\x05\x10\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x04\x01\x00\x3b");
Creating such a string is easy with regular expressions (as it's done once, it doesn't have to work fast):
echo preg_replace('/../','\\x\0',bin2hex($data));
Or from a file:
echo preg_replace('/../','\\x\0',bin2hex(file_get_contents($filename)));
To answer some people's questions:
You must echo the contents of an image. The Header only shows that are you are returning an image to the browser, instead of normal text. So if you only return a header, it's just a header - no data. However, print out data of an image and done, you just sent an image :)
Reading a file is not good, it could work, but it's better to return raw data like shown in main answer by Sjoerd. This way, you save time and server load not having to process a read operation. Reading from disk is a slow task. Over time, reading from disk has increased in speed with SSD disks, but still, No I/O to disk is better.
I had this code even without base64 decode, but this image has white color:
header('Content-Type: image/gif');
// 1x1px white gif
die("\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2a\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b");
Maybe someone knows how to convert any file to such data string?
header('Content-Type: image/gif');
printf('%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%', 71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 255, 0, 192, 192, 192, 0, 0, 0, 33, 249, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59);
In Linux you can convert it by typing in console:
hexdump -v -e '"\\\x" 1/1 "%X"' image.gif; echo

php gd image quality

I 'm trying to add text on a specific image. Its working perfectly but the quality of image is low especially for papyrus.ttf font. How can i improve the quality of text in the image. But i need high quality to print the output.
Here is my code.. its very simple.
header("Content-Type: image/jpeg");
$im = imagecreatefromjpeg("cosmos.jpg");
$black = ImageColorAllocate($im, 0, 0, 0);
Imagettftext($im, 14, 0, 10, 15, $black, 'papyrus.ttf', "Corey and Lisa ");
Imagettftext($im, 14, 0, 10, 35, $black, 'papyrus.ttf', " 1994, june");
Imagejpeg($im, '', 100);
ImageDestroy($im);
Download: http://wneeds.com/gdtest.zip
If imageTTFText fails in Quality, the next step to try is ImageFTText(). It uses the FreeType library to render fonts, which usually means significantly better quality. It needs to be installed and compiled into PHP to work, which it most often is. Try calling the function and you'll see whether that is the case.
If that doesn't do, the next step is using ImageMagick either through the command line, or through the appropriate PHP extension. But try Freetype first, it could already be enough.

Categories