ImageMagick displays garbled text instead of image - php

I am trying to use ImageMagick class functions in PHP.
To get familiar with ImageMagick, I wrote a few lines of code in PHP to display a red square in my browser.
Instead of displaying a red square, I get garbled text.
I know ImageMagick is installed because I can use ImageMagick functions to save the red square to a file.
Thanks in advance for any help for this newbie to ImageMagick and StackOverflow!
Here's my PHP code:
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');
$image->writeImage("MyOutput.png");
header('Content-type: image/png');
echo $image; //This causes just raw text to be displayed. :(
echo '<img src=MyOutput.png>'; //Displays a 100x100 red image!
//..So, ImageMagick IS installed.
Here's my full PHP file.
<!DOCTYPE html>
<head>
<title>ImageMagick Test</title>
</head>
<body>
<?php
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');
header('Content-type: image/png');
echo $image;
?>
</body>
</html>

The main problem you have is that you're sending Content-Type: image/png after putting some output. Once you put any output, PHP immediately sends all response headers and proceeds to the body part of response. The default Content-Type is text/html on most servers, so your browser is interpreting image content as HTML, and thats why you're seeing some garbage. It's a bit like opening PNG file in notepad.
See this question for more information about sending response headers
Also you can't return HTML and image content upon one request, so do not put any HTML in your image-generating file. The image is independent file and it has to be returned upon it's own, separate request, containing only headers, image bytes and nothing more.
This should work:
<?php
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');
header('Content-type: image/png');
echo $image;
Note, that this is whole PHP file and you can't send any other output neither from outside of <?php ?> nor by echoing.
If you want to include your image into HTML you need a second file (it may be plain HTML), which should look as follows:
<!DOCTYPE html>
<head>
<title>ImageMagick Test</title>
</head>
<body>
<!-- here we're including our image-generating PHP script -->
<img src="imagickTest.php">
</body>
</html>
Then you can refer either to PHP file if you want to see only image or to HTML file if you want to see image put into HTML context.

Related

Using header('Content-type: image/png') and echo"<html>" in one .php [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to use imagecreatefromjpeg, imagecreatetruecolor, imagecopyresized and imagejpeg while making use of the echo "<html><body>"; etc...
For some reason I get "The image could not be displayed because there were errors on the page" until I comment out header('Content-type: image/png'); and then I just get a picture of a broken picture, like a torn page.
All I've seen is that I can't have header('Content-type: image/png'); and html in the same .php file. If that's the case can anybody tell me how to resize an image for a thumbnail gallery while still having html in a .php file?
Thanks in advance.
You are mixing up two different things.
A webpage with an image on it, does not contain that image in general. Instead, it often refers to an external source. I said in general, because, yes, an image can be embedded in an HTML page, see below.
You have two options:
You can create an apart PHP file where you create the image and output its bytes. In your HTML code, you refer to that image:
page.html:
<html>
<body>
<img src="myimage.php" alt="" />
</body>
</html>
myimage.php:
<?php
header("Content-Type: image/png");
createimageandso_on();
// Do the drawing.
?>
Or you can embed the image in your HTML file, using base64 encoding:
<?php
$contents = all_bytes_from_created_image();
// Get the bytes from the created image.
$base64 = base64_encode($contents);
?>
<html>
<body>
<img src="data:image/png;base64,<?php echo $base64; ?>" alt="" />
</body>
</html>
The second option is suitable for smaller images, since the base64 encoded string will produce large portions of text.
Edit
If I understand it correctly, you want to read images from a directory and resize them to the same size, using them as thumbnails?
What you might just want to do is create a PHP file where you read a source image and give them the same size.
Just like 'normal' PHP files, PHP can do something with the request parameters you give. Perhaps you've ever seen this:
http://example.com/somepage.php?key=value&anotherkey=anothervalue
That string behind the question mark (key=value&anotherkey=anothervalue) is the query string. PHP can do something with the values:
<?php
echo $_GET['key']; // returns "value"
echo $_GET['anotherkey']; // returns "anothervalue"
?>
Now we can just do the same when creating an image. You don't have to make twenty PHP files with almost the same code, but just a single file which reads a file (you name it) and resizes it to the specified width (you name it) and height (you name it).
thumbnail.php
<?php
// Get some request parameters we're going to use.
// We're expecting the parameters below to exist.
$file = $_GET['filepath'];
$width = $_GET['width'];
$height = $_GET['height'];
// Now we're gonna create the image from the given file.
$src = imagecreatefromjpeg($file);
imagecreatetruecolor($width, $height);
// And the rest of the file reading and image creation.
header("Content-Type: image/jpeg");
imagejpeg($image);
?>
webpage.html
<html>
<body>
<?php
$width = 100;
$height = 100;
$files = read_some_directory_and_return_a_list_of_filenames();
foreach ($files as $file) {
// Echo an image tag in the HTML document;
// use as image our thumbnail.php file and give it a query string:
echo "<img src=\"thumbnail.php?width=".$width."&height=".$height."&filepath=".$file."\" alt=\"\" />";
}
?>
</body>
</html>
What you've seen is correct - you can't have a file with Content-type: image/png that contains html contents. The browser will interpret the html code as encoded html data, which is wrong.
What you should do is leave the content type as text/html and send the image in an html document, as in my example below. I left out the <head> for simplicity, but you should add one.
<!DOCTYPE html>
<html>
<body>
<img src="myimage.png" width="100" height="100" />
</body>
</html>
You cannot have markup inside your image you want to push down to the browser. You're telling the browser to expect an image and then sending down some markup, that's a no-no.
What we can do is include a .php file which uses your imagecreatetruecolor, etc... functions inside some img tags:
<html>
<head><title>Image Test</title></head>
<body>
<img src="image.php?file=A" />
<img src="image.php?file=B" />
</body>
</html>
Then image.php would use our image/jpeg headers and contain your imagecreatefromjpeg code.
<?
header('Content-Type: image/jpeg');
if ($_GET['file'] == 'A') {
$img = imagecreatefromjpeg('image1.jpg');
} elseif ($_GET['file'] == 'B') {
$img = imagecreatefromjpeg('image2.jpg');
}
// do your modification etc... here
imagejpeg($img);
imagedestroy($img);
You can only output "image code" in your image.php file because the browser is going to treat it as if it's a regular jpeg.

how do I call create image function?

I found this topic: convert text to image in php
and I tested the code that Sourabh Shankar provide.
When I paste this code in a new empty php file and I adjust the font path, then it works perfect!
But when I put a echo before or after the header('Content-type: image/png'); line, then it all fails
Can someone provide me a code of how to call this image creator in a HTML file:
example:
<span>Here comes the image</span>
<?php [call function??] ?>
<span>and here we continue with some HTML</span>
Do I need to create a php function and if so:
what do I excactly return?
if I return this:
imagepng($im);
then he wont execute the
imagedestroy($im);
I'm not sure how to do this
The PHP code you linked to works as a stand-alone file, so that when it is requested in a browser it will send back an image. Setting the header with
header('Content-type: image/png');
means that the code will return content which the browser interprets as an image file, rather than a HTML file.
You couldn't use PHP to directly output a file into HTML. You would need to use that code in a separate file and link it to the src tag of an image in your code.
You need get image from other script via http.
<span>Here comes the image</span>
<img src="/path/to/image_handler.php"/>
<span>and here we continue with some HTML</span>
where image_handler.php - your php script:
<?php
…
header('Content-type: image/png');
imagepng($im);
NOTE: never output something before call header

Generating QR Code using PHP QrCode

After using the PHP QrCode lib I discovered that for some reason when using a dynamic page with scripts and dialog boxes (JQuery) that when trying to output a QR code in a .png format I get weird symbols instead of the actual generated .png file.
Heres what I have tried:
Created a seperate file with just:
<?php
//include only that one, rest required files will be included from it
include "phpqrcode/qrlib.php";
QRcode::png('barrda554');
?>
Works great,
Attempt 2:
File opened within a dialog box type using JQuery UI:
<?php
header stuff...
include "phpqrcode/qrlib.php";
...
?>
<html>
...
<?php
QRcode::png('barrda554');
?>
..
</html>
In this attempt I get multiple funky symbols for some reason:
�PNG IHDRWWKK/PLTE���U��~�IDAT8��ѱ � P# �c��n :V�L�#�k
y��)�|F��5`ڸzHF|l���
%Z"e�Ы�D{\�ގ����p`�f�eh�������k�[BJeJ�c����,�^�gu�m|Q��o��W����g�
�#�s�<�y��k�m��!v�.��(+�u���$s�-�n$߫>�gR�`IEND�B`�
This has stumped me and I am unsure on how I should approach this to fix it.
Let me know your ideas,
David
UPDATE:
After putting header('Content-Type: image/png'); within the file that JQuery opens, no cigar.
Here is the actual file:
http://jsfiddle.net/T4nEP/
The problem is here:
<html>
<?php
QRcode::png('barrda554');
?>
</html>
To understand what this is doing, imagine that you open a regular PNG file in a text editor, and just copy/paste the contents directly into your HTML file. It's not going to show an image - it'll just be garbage, like you're seeing.
To include an image in an HTML file, you need to use the <img> tag, and point to the URL of the image. In this case, the URL of the image would be a PHP script that outputs nothing except the PNG contents - like this:
<img src="qrcode.php">
And then in qrcode.php, generate the image:
<?php
include "phpqrcode/qrlib.php";
QRcode::png('barrda554');
?>
If you need some information from the HTML page in order to generate the image, you can include it as query parameters in the URL, like this:
<img src="qrcode.php?product=1&format=2">
And then get those values in your PHP like this:
<?php
include "phpqrcode/qrlib.php";
$product = $_GET['product'];
$format = $_GET['format']
// ...
// whatever you need to do to generate the proper code
// ...
QRcode::png('barrda554');
?>
And finally - there are ways to include the image data directly into the HTML page, but it's not supported by all browsers, and is not recommended because it makes the page size much larger and prevents the browser from being able to cache the image separately.
You can see more about base64 data URLs here and here.
Make sure you have the following php code to generate the correct Content-Type header so the browser knows how to render the data its receiving.
header("Content-Type: image/png");

Outputting raw image stream rather than jpeg, on-the-fly image resizing

I have a PHP function that does on-the-fly image resizing for thumbnail creation.
I am having trouble as it's just displaying raw image stream instead of the actual image.
My code is using a function called thumbnail:
$thumbnail = thumbnail($item['filename'], 209, 137);
imagejpeg($thumbnail);
I've tried putting in:
header("Content-type: image/jpeg");
However, this just expects the full page to be an image. I have absolutely no idea where to go from here, been working at it for a while. I'd rather not save the image to disk although it's looking like this might be necessary.
You either
Do it the normal way
This mean you point at one url, and serve the contents of one image:
<img src="myimage.php">
and myimage.php is a script that looks like:
header('Content-type: image/jpeg');
imagejpeg($thumbnail);
die;
This technique has the advantage of being.. the normal way of doing things.
OR
Output the image inline
Using data uris outputting the contents as a base64 encoded string
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
This technique is most appropriate with small images.
It has the advantage of meaning all the images are in the main http request - at the (possibly sizable) disadvantage of making the page harder to edit/build and possibly negating the benefits of browser caching (unless the html page is itself cached).
Being normal is easier
Regarding this statement in the question:
However, this just expects the full page to be an image
That's right - if you do it the normal way you want to point at your php script with the src attribute of an image tag, and server only an image - i.e. the exact same response as if you were pointing at an image file with a browser.
Unless you have a good reason to do things a different way - the "normal" way is a good place to start.
You can point an html img tag to an php file.
<img src='thumbnail.php?file=<?php echo $item['filename']; ?>' />
Then on your php file you display the image and change the headers since all it is doing is displaying an image.
$thumbnail = thumbnail($_GET['filename'], 209, 137);
imagejpeg($thumbnail);
header("Content-type: image/jpeg");
You need to insert the image like you would a normal image in HTML and create the image in a separate PHP file:
image.php
<?php
$img = imagecreate(100,100); //Create an image 100px x 100px
imagecolorallocate($img, 255,0,0); //Fill the image red
header('Content-type: image/jpeg'); //Set the content type to image/jpg
imagejpeg($img); //Output the iamge
imagedestroy($img); //Destroy the image
?>
myWebpage.html
<img src="image.php" />

The image cannot be displayed because it contains errors

Why is this code not working ?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
<?php
header('Content-type: image/png');
$myImage = imagecreate(200, 100);
$myGray = imagecolorallocate($myImage, 204, 204, 204);
$myBlack = imagecolorallocate($myImage, 0, 0, 0);
imageline($myImage, 15, 35, 120, 60, $myBlack);
imagepng($myImage);
imagedestroy($myImage);
?>
</body>
</html>
I always get error The image cannot be displayed because it contains errors.. I've already enabled php_gd2.dll and memory_limit in php.ini is also 128M. If i remove header('Content-type: image/png'); i don't get the error but i don't see the image either. All i see is this :-
‰PNG ��� IHDR���È���d���ùHíH���PLTEÌÌÌ���Ó33d���MIDATH‰c£Àx�§” Nf*k²Ã)Ãø�§”•5}À)ÅS†ÚšpJUà”a§²¦œ2ÔŽw<špJ‚Q0 †;�� uTBúŸ����IEND®B‚ `
You must not output anything before header(). Just start your document with <?php (as the first file characters), followed by the code for displaying the image. Skip the HTML tags. Do not even write a single blankline before header().
If you want to display an image inside the html document of yours, you must do it in two files. One, call it for example image.php, containing only the PHP code including the header. The second file, call it show.php or show.html, includes the HTML code you like, including <img src="image.php" alt="Your generated image" />.
If you base64 encode the output, you could use the image directly with a Data URI scheme.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
<?php
$myImage = imagecreate(200, 100);
$myGray = imagecolorallocate($myImage, 204, 204, 204);
$myBlack = imagecolorallocate($myImage, 0, 0, 0);
imageline($myImage, 15, 35, 120, 60, $myBlack);
ob_start();
imagepng($myImage);
printf('<img src="data:image/png;base64,%s"/>',
base64_encode(ob_get_clean()));
imagedestroy($myImage);
?>
</body>
</html>
Note that Data URIs are not supported by all browsers (guess which).
You should output only the image. You are outputting a bunch of tags. Specifically
<!DOCTYPE HTML PUBLIC "-//W3C//DTD
HTML 4.01 Transitional//EN">
<title></title>
</head>
<body>
and then the image as a binary. If you want to see this, wget the page from your server and try opening it in an editor. Your code should start at the <?php.
Removing the header gets rid of the notification to the client that this is an image so it will try out print it out as text.
While trying to output a jpg of a Facebook profile-picture from their Graph API with PHP,
I noticed that if the PHP file is saved with UTF-8 encoding - this error was returned,
but if the file was saved with ANSI encoding -
then it worked OK.
If you have this problem, try to delete any space character between the begin of the script and the php tag
> <?php
I spent several hours before realize this. And now it works OK. This happens because any character on the file alter the png format. This worked great for me.
Even if you think you have removed all the text from before header() your PHP file may contain a Byte Order Marker
This will be invisible to you in your editor, but your browser will see it and think the image is corrupt. You need to take the steps appropriate to your editor to remove any BOM.
This is all you need. You can not print anything else because it needs to look like it's own file. You could call this image.php and pass it a variable to define which image to output.
<?php
header('Content-type: image/png');
$myImage = imagecreate(200, 100);
$myGray = imagecolorallocate($myImage, 204, 204, 204);
$myBlack = imagecolorallocate($myImage, 0, 0, 0);
imageline($myImage, 15, 35, 120, 60, $myBlack);
imagepng($myImage);
imagedestroy($myImage);
?>
I isolated the PHP script into its own file (image.php) and it worked fine: I got a grey rectangle with a black slanted line. Your issue is trying to embed this within a HTML file.
You need the PHP in its own, separate file (as I did, call it image.php or something more description to your needs) and then create a HTML file as follows:
<html>
<head>
<title>Document Title</title>
</head>
<body>
<img src="image.php" alt="" />
</body>
</html>
You should get your desired output then.
I had the same problem and the solution was to change the charset of the code from UTF-8 to ansi or viceversa. If the server is set to UTF-8 and your code is in ansi this don't work and if your code is in ansi and the server is configured to UTF-8 neither.
If you are using Filezilla to upload your webpages make sure you select transfer type as 'Auto/Binary'.
Transfer -> Transfer type -> Auto/ Binary.

Categories