imagejpeg shows a blank image for creating captcha - php

I tried 3 different codes to create a captcha for my php project,but they all showed gibberish html instead of actually executing it.
I tried both imagepng and imagejpeg and even added the header attribute,but instead of working,it shows nothing but a blank image in the middle of the browser page.I looked up all stack overflow questions for this,but none seems to work for me.
When I remove the header attribute it writes gibberish but when I remove it it shows me a blank image.Is there anyone that can help me?
Here's the last code I coded:
<?php
session_Start();
$length = rand(0,56);
$shuffle=str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
$text = substr($shuffle,$length,6);
$_SESSION["captcha"] = $text;
$im = imagecreatetruecolor(18,22);
imagecolorallocate($im,255,255,255);
$fontSize = 24;
$rotate = 13;
$xRotate = 50;
$yRotate = 70;
$font = getcwd()."\\public\\fonts\\arial.ttf";
$color = imagecolorallocate($im,255,0,255);
imagettftext($im,$fontSize,$rotate,$xRotate,$yRotate,$color,$font,$text);
header('Content-Type: image/jpeg');
imagejpeg($im);
?>

Related

Why is php code not giving the output of image?

this is the code
<?php
$x = imagecreatetruecolor(250, 250);
$y = imagecolorallocate($x, 120 ,156,100);
header('Content-Type: image/jpeg');
imagejpeg($x);
?>
It is giving output as
The image "http://localhost/firstprogram.php" cannot be displayed because it contains errors.
I also tried Example from https://www.php.net/manual/en/function.imagerectangle.php and it still displayed the same message.
And also can someone tell if header is necessary or not and what exactly is it used for?
you made a image, you allocate it, but you did not draw it.
try this code
<?php
$x = imagecreatetruecolor(250, 250);
$y = imagecolorallocate($x, 120 ,156,100);
imagerectangle($x, 50, 50, 150, 150, $y);// draw the rectange of image
header('Content-Type: image/jpeg');
imagejpeg($x);
?>

Rotated image wont display in php

So i am trying to create a compass to show wind direction.
Function rotate($angle) {
$original = imagecreatefrompng("img/Arrow.png");
$compass = imagerotate($original, $angle, 0);
return $compass;
}
That will be displayed using some html that i am echoing. The variable angle is being passed from a database. The html on the php script looks like this:
<img src='".rotate($row['wind_dir'])."'/>
The image never displays, and clearly the browser does not know where it is.
When i view the html in my browser, the above line shows as
<img src="Resource id #4"/>
and when i click on it, it navigates to a 404.
What am i doing wrong? Have i forgotten a line in the image rotation function?
EDIT:
Having tried some of the responses below, i get an image, but it only shows as a black box!
EDIT2:
Well after much fiddling, it turns out all that was needed was to the third value of imagerotate() to -1 as follows:
$original = imagecreatefrompng("img/goog.png");
$compass = imagerotate($original, $angle, -1);
imagealphablending($compass, true);
imagesavealpha($compass, true);
header('Content-Type: image/png');
imagepng($compass);
imagedestroy($compass);
I posted a comment about using CSS or JS rotation instead but since then I've had a better idea.
The compass is always going to be Arrow.png in one of 360 positions.
Use a batch process in Photoshop or PHP to create 360 versions. One for each degree. Then you can just call Arrow_120.png for example for 120 degrees. You remove the issue with your existing code of creating images on the fly while avoiding compatibility issues with CSS / JS.
You have to execute the function and send header: try like below, say our php file name is rotate.php :
rotate.php
function rotate($angle) {
$original = imagecreatefrompng("test.png");
$compass = imagerotate($original, $angle, 0);
header('Content-Type: image/png');
imagepng($compass);
imagedestroy($compass);
}
if(isset($_GET['angle'])){
rotate($_GET['angle']);
}
THen in your html you can call the web resource i.e you php file as:
<img src="url_to_rotate.php?angle=90" />
Also remember to sanitize the GET input before executing it.
The displayed image should be a image file. To achieve this you should use imagejpeg();
So basically you should have 2 php files:
1: Creates the image file using your code and imagejpeg();
<?php
$original = imagecreatefrompng("img/Arrow.png");
$compass = imagerotate($original, $_GET['angle'], 0);
header('Content-Type: image/jpeg');
imagejpeg($compass);
?>
2: The php file that displays the image.
<img src='image.php?angle=".$row['wind_dir']."'/>
if you want just one file you could do the following:
<?php
$original = imagecreatefrompng("img/Arrow.png");
$compass = imagerotate($original, $_GET['angle'], 0);
ob_start();
imagepng($compass);
$stringdata = ob_get_contents();
ob_end_clean();
$imageData = base64_encode($stringdata);
$src = 'data: image/png;base64,'.$imageData;
echo '<img src="',$src,'">';
?>

resize image on the fly using php

I'v searched all day for a function to resize my pictures on the server on the fly, without saving them.The code works, it shows the full size images, now I want to make them smaller.
This is the function:
function resize_image($file, $width, $height) {
if (file_exists($file)){
$image = imagecreatefromjpeg($file);
list($orig_width, $orig_height) = getimagesize($file);
$ratio = $orig_width / $orig_height;
if ($ratio < 1) {
$width = $height * $ratio;
} else {
$height = $width / $ratio;
}
$new_image = imagecreatetruecolor($width, $height);
imagecopyresized($new_image, $image,
0, 0, 0, 0,
$width, $height,
$orig_width, $orig_height);
// header('Content-type: image/jpeg');
imagejpeg($new_image, NULL, 80);
}
}
From what I searched today I need to put the header (Content-type: image/jpeg') for the browser to recognize the output as an image but if I do that it stops the script.
This is the page using it:
<? include('resize.php');
$chapter='test';
$query=$db->prepare("SELECT * FROM `test_db` WHERE `test_db`.`Chapter` LIKE :? ORDER BY `id` ASC LIMIT 0, 6");
$query->bindValue(1, $chapter, PDO::PARAM_STR);
$query->execute();
$rows= $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row){
echo "<li><h2>".$row['Name']."</h2></li>" ;
resize_image("_images/".$row['img_number'].".jpg", 300, 190);
};
?>
You cannot output html and images to the browser in the same script.
You should either:
use a separate script to output the image and call that from the html like (simple example):
<img src="your_script.php?id=XX&size_x=XX&size_y=XX">
save the images to a file and link to that file from your html.
You could also encode the images as base64 strings and use that in your image tags but that would lead to a very large html file unless you are talking about simple buttons.
Don't put your closing tag in PHP. It will output whitespace after the closing tag which will alter the result.
Since when are headers stopping the script?
And yes, the reason why resized files are saved, is (1) you'll probably need them again, (2) the content type makes them an image in stead of text. If you want to resize those 'inline' you'll need two content types, and I guess that won't work that well...
What you could do, is resize and save the file, serve it and delete it. Like a temporary image file. A more direct way doesn't exist, according to me. But if I'm wrong, please point that out in the comments for me. I like to learn new stuff ;)
Edit: okay, EXCEPT when the script only handles the image resizing. Just thinking about that one right now. Sorry :)

PHP header, Content type: image not allowing text

I have a variable ($output) that is set to a string.
To mekt this string an image I'm using the PHP: GD Library.
In particular the imagestring() function, which I'm using with a very slight modification:
<?php
// Create a 100*30 image
$im = imagecreate(100, 30);
// White background and blue text
$bg = imagecolorallocate($im, 255, 255, 255);
$textcolor = imagecolorallocate($im, 0, 0, 255);
// Write the string at the top left
imagestring($im, 5, 0, 0, $output, $textcolor); #here is my string $output
// Output the image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
This is working as expected: It turns $output into an image.
So, my problem is (or my best guess at least):
header('Content-type: image/png');
Which, doesn't allow me to output any html after that.
So I read this question, which asks if you can use two headers, which you can't, but the accepted answer recommends, something like this: <img src="my_img.php" />
This of course would be fine, except I don't know how would this solve my issues since, since even if I knew the source to this image (which I don't - so, that would be my first question, what's the path to the generated image*) I't would change the fact that the header is there and is not letting me output text.
So, I how would you approach this issue?
Thanks in advance!!
*I guess that would solve my issues since I could do this on an external file, and the just call the image (but maybe not since I would have to do an include and this would include the header too) as you see I'm a bit confused. Sorry :)
UPDATE:
So I'm seeing my question was confusing so I will add some more code to see if this clarifies my problem a little bit more:
<?php
$x = mt_rand(1,5);
$y = mt_rand(1,5);
function add($x, $y) { return $x + $y; }
function subtract($x, $y) { return $x - $y; }
function multiply($x, $y) { return $x * $y; }
$operators = array(
'add',
'subtract',
'multiply'
);
$rdno = $operators[array_rand($operators)];
$result = call_user_func_array($rdno, array($x, $y));
session_start();
$_SESSION['res'] = $result;
if ($rdno == "add") {
$whato = "+";
}elseif ($rdno == "subtract") {
$whato = "-";
} else {
$whato = "*";
}
$output = $x . $whato . $y . " = ";
?>
<form name="input" action="check.php" method="post">
<input type="text" name="result" />
<input type="submit" value="Check" />
</form>
I want $output to be a image so this got me trying to use the PHP:GD script above, but I can't make put in the same file because of the header.
You need to make a separate PHP script which serves the image, then make an <img> tag that points to this script.
You can send information to the script using the querystring in the image URL.
Morbo says: "Windmills do not work that way! Goodnight!"
Which means that you need to bone up on how this all works. This issue points to you having a basic misunderstanding of your tools. HTML can't contain images, it contains links to images. So your script needs to be included from another page via an image tag. (or CSS)
However, all this is a good thing. It means that this script can have dynamic elements that produce a new image each time it is called. Or that it could password-protect your images so only logged-in users can see it.
There are a host of ways to use this. And once you realize the image is like a page to php, this opens new routes. Php can output anything. Word docs, excel, pdf, css, even JS. all of which can be used to do cool things.
Just think of the image as a separate page. You'll get it. It'll just click into place in your mind. One of those big 'aha' moments.
First, the path.
From the manual :
imagepng ( resource $image [, string $filename [, int $quality [, int $filters ]]] )
It means that if you don't give a second argument (it is the case here), you don't have the path to a file but the data of the file / image ressource. The php file will be understand as a png file by the browser thanks to the header you give.
Second :
In your page (ie index.php), you could add this like that
<img src="myimg.php?output=[...]" />
and in your php script myimg.php you have it like this :
<?php
$output = $_GET['output'] // getting your text
// Create a 100*30 image
$im = imagecreate(100, 30);
// White background and blue text
$bg = imagecolorallocate($im, 255, 255, 255);
$textcolor = imagecolorallocate($im, 0, 0, 255);
// Write the string at the top left
imagestring($im, 5, 0, 0, $output, $textcolor); #here is my string $output
// Output the image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
2 separates files.
You can send the image inline with echo '<img src="data:image/png;base64,'. base64_encode(imagepng($im)) .'" /> instead of <img src="my_img.php">.
Do not set a content-type header! Your output is text/html what you don't have to announce as it's the default in most server setups.
HTTP doesn't work that way. When your are serving image/png data, it as if you are serving a png file from the site, not an html file with an image in it. What are you trying to accomplish?
my_img.php is not source to your image. It is a source to the script generating that image, or reading it from file and outputting directly into browser. Obviously the approach with img src would be the best, because you'll hide all "boring" implementation of displaying image string behind browser's mechanisms.

Problem displaying image with imagejpeg in PHP

I'm having an issue using a watermarking script I have. Below is the script:
if (isset($_GET['imgid'])) {
include "../mysql_connect.php";
$imgid = $_GET['imgid'];
$query = "SELECT * FROM img_ref WHERE id='$imgid'";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result);
$imagesource = "../ajax_uploads/$row[submitter_id]-uploads/$row[filename]";
} else {
$imagesource = "../ajax_uploads/" . $_GET['path'];
}
$info = pathinfo($imagesource);
$filetype = $info['extension'];
if($filetype == "gif") $image = #imagecreatefromgif($imagesource);
if($filetype == "jpg") $image = #imagecreatefromjpeg($imagesource);
if($filetype == "png") $image = #imagecreatefrompng($imagesource);
if (!$image) die();
$watermark = #imagecreatefrompng('../images/watermark.png');
// This is the key. Without ImageAlphaBlending on, the PNG won't render correctly.
imagealphablending($image, true);
$imagewidth = imagesx($image);
$imageheight = imagesy($image);
$watermarkwidth = imagesx($watermark);
$watermarkheight = imagesy($watermark);
$startwidth = (($imagewidth - $watermarkwidth)/2);
$startheight = (($imageheight - $watermarkheight)/2);
imagecopy($image, $watermark, $startwidth, $startheight, 0, 0, $watermarkwidth, $watermarkheight);
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark);
Now, if I pass a 'path' variable through, everything works fine and the image is displayed correctly as I would imagine. However, when I attempt to pass through an imgid value, and retrieve the path from the database, the image is presented in raw data on the screen - not as an image.
I have tried specifying the headers
header("Content-type: image/jpeg");
However that hasn't helped. It doesn't seem to be an issue with the folder permissions, as if I specify the path name using the reference in the database, it works fine. It seems to be that including that first "if" section seems to break the output, and I'm at a loss why.
Could anyone possibly shed any light on this for me?
Thank you kindly,
Dan
UPDATE
Okay, somehow its started working with having "Header("Content-type: image/jpeg");" placed at the top of the PHP file, so if I go to the file directly and put in the GET id, I get the picture returned - which is good (no idea what changed though).
However I still have an issue in displaying this picture elsewhere it seems. I'm calling the picture using "fancybox", a jquery plugin. When it displays the image, it is still showing the raw data. If I use the path, it displays fine - just for some reason the raw data shows up when using the GET id option. Am still looking into it but thanks for suggestions so far.
It seems using the header
header("Content-type: image/jpeg");
Seemed to work to get it to display as an image - however it did not work with fancybox for some reason. I looked at the API and have sinced forced fancybox to realise it is an image:
$.fancybox({
'href':'processes/process_watermark.php?imgid=' + id,
'type':'image'
});
That makes it display correctly.
Thanks for everyones help - and all the comments reminding me about SQL attacks.
You don't checking fail of mysql_fetch_array maybe query dont result anything?
Maybe path you giving to pathinfo is not correct.
Your debugging script you should have at the top of script error_reporting(E_ALL)
Change $imagesource = "../ajax_uploads/$row[submitter_id]-uploads/$row[filename]"; to $imagesource = "../ajax_uploads/" . $row['submitter_id'] . "-uploads/" . $row['filename'];

Categories