I've built an image gallery and saved the image "as is" without cropping it. I want to resize the image on the fly while it's loaded in the controller, so when I load the controller in the browser it displays the image re-sized to whatever I want. I've added the method to MY_Loader, here is the code.
function show_image($image, $width, $height) {
$this->helper('file');
$image_content = read_file($image);
//resize image
$image = imagecreatefromjpeg($image);
$thumbImage = imagecreatetruecolor(50, 50);
imagecopyresized($thumbImage, $image, 0, 0, 0, 0, 50, 50, $width, $height);
imagejpeg($thumbImage,"",85);
imagedestroy($image);
imagedestroy($thumbImage);
header('Content-Length: '.strlen($image_content)); // sends filesize header
header('Content-Type: '. get_mime_by_extension($image)); // send mime-type header
header('Content-Disposition: inline; filename="'.basename($image).'";'); // sends filename header
exit($image_content); // reads and outputs the file onto the output buffer
}
From this code, I'm getting many errors including header errors. What am I doing wrong?
Errors: (if useful)
Message: imagejpeg(): Filename cannot be empty
Message: Cannot modify header information - headers already sent by (output started at /Volumes/www/vhosts/ci/system/core/Exceptions.php:185)
Message: strrchr() expects parameter 1 to be string, resource given
Message: Cannot modify header information - headers already sent by (output started at /Volumes/www/vhosts/ci/system/core/Exceptions.php:185)
Message: basename() expects parameter 1 to be string, resource given
Message: Cannot modify header information - headers already sent by (output started at /Volumes/www/vhosts/ci/system/core/Exceptions.php:185)
Ok... so...
the fist thing is, that you does not want to save image, just display
so you should use imagejpeg with only one parameter.
function show_image($image, $width, $height) {
//$this->helper('file'); why need this?
//$image_content = read_file($image); We does not want to use this as output.
//resize image
$image = imagecreatefromjpeg($image);
$thumbImage = imagecreatetruecolor(50, 50);
imagecopyresized($thumbImage, $image, 0, 0, 0, 0, 50, 50, $width, $height);
imagedestroy($image);
//imagedestroy($thumbImage); do not destroy before display :)
ob_end_clean(); // clean the output buffer ... if turned on.
header('Content-Type: image/jpeg');
imagejpeg($thumbImage); //you does not want to save.. just display
imagedestroy($thumbImage); //but not needed, cause the script exit in next line and free the used memory
exit;
}
fist round i recommend this changes. Please write me, what changes with errors...
And recommend to read: http://php.net/manual/en/function.imagecopyresized.php
And this :
Message: Cannot modify header information - headers already sent by (output started at /Volumes/www/vhosts/ci/system/core/Exceptions.php:185)
Says me that something is wrong with the exception php...
please check, is BOM character at the begining of the file... or is spaces, newlines after .. or before the php tag.. some code editor puts these irritatign characters in php code...
And any other files (that appears this error message) should be checked like this.
Sometimes some characters left before the php tag... and if output bufering is turned off as the webservice reads the file, send to the output inmedietly with the default header.
( recently html/text header ) . ( some headers can't be sent if other header sent already.. for example if html/text sent, image/jpeg cannot be sent )
if you do not want to work a lit with this. I doesnt know how your system looks like.
I assume that index.php is your bootstrap, change it.
<?php
ob_start();
....
ob_end_flush();
?>
But better solution to examine your php codes, and delete lines / characters before and after php tag.
Related
I'm trying to create a dynamic image generator that also caches the images.
Everything works perfectly, except that for some reason when I save an images and try to display it at the same time, it shows a broken image icon (like: http://cl.ly/image/3K1f0R0n1R0U).
Code sample:
// some string parsing junk happens up here, but removing that didn't change
// what I've been having a problem with
header("Content-type: image/png;");
if(file_exists($fullFileName)){ // serve the file if it already exists
ob_clean();
flush();
readfile($fullFileName);
exit;
} else { // create the file if it doesn't exist
$my_img = imagecreate(200, 80);
$background = imagecolorallocatealpha($my_img, 0, 0, 0, 127);
$line_colour = imagecolorallocatealpha($my_img, $color["r"], $color["g"], $color["b"], $color["a"]);
imagesetthickness($my_img, 1);
imageline($my_img, 30, 45, 165, 45, $line_colour);
//////////////////////////////////////////
// the line that's causing my troubles: //
//////////////////////////////////////////
imagepng($my_img, $fullFileName);
imagecolordeallocate($line_color);
imagecolordeallocate($background);
imagedestroy($my_img);
}
So, the images are created just fine, save just fine, and display exactly like I want when I refresh the page (because it grabs the saved file).
If I switch that darn line above to:
imagepng($my_img);
Then the image shows up fine, but it doesn't save (since I'm not telling it to).
I thought that this topic:
PHP echoing jpeg image fails, but writing same image to file works great. Why?
Sounded similar, but removing the trailing white space still didn't change what's happening. Other threads mentioned it could be a problem with other content being sent before the headers, but there is nothing like that in this file.
Any ideas on what could be going wrong? No errors are being logged, and I'm out of ideas.
Thanks!
-Zach
EDIT:
It was explained that I was destroying my image, which I missed. I ended up using this:
header("Content-type: image/png");
if(!file_exists($fullFileName)) {
$my_img = imagecreate($dashWidth + $dashSpace, $height);
$background = imagecolorallocatealpha($my_img, 0, 0, 0, 127);
$line_colour = imagecolorallocatealpha($my_img, $color["r"], $color["g"], $color["b"], $color["a"]);
imagesetthickness($my_img, 1);
imageline($my_img, 0, $height-1, $dashWidth-1, $height-1, $line_colour);
imagepng($my_img, $fullFileName);
imagecolordeallocate($my_img, $line_color);
imagecolordeallocate($my_img, $background);
}
ob_clean();
flush();
readfile($fullFileName);
exit;
you mean
header("Content-type: image/png"); // without ;
and also, you are destroying your image, read again the file
readfile($fullFileName);
because imagepng($my_img, $fullFileName); only saves it.
From the manual, imagepng
Outputs or saves a PNG image from the given image
Note the "or". Try making two calls to imagepng. One call to save it to a file and one call without the filename parameter to output the image to the browser.
Try to open image with you text editor.
Turn off error_reporting.
Show you broken image.
I am doing an assignment for school where we are to make two php files. First file invokes session, generates a random 5 char string, and saves the string to the session array. The second script generates an image, and takes the string from the first file and incorporates it over the image to make a captcha.
I am having an issue passing the value to the second script. The session variable 'captcha_string' is fully visible in the first script, but is not passed to the second page. I am brand new at this, and frustrated. My understanding is, that as long as I start session, the entire $_SESSION array should be available. When I run the first script, I get a broken image tag, not the captcha i am hoping for. Hope this clears up my problem.
This is what I have done for the first file:
<?php
session_start();
$possible_chars = array_merge(range('A','Z'),range('0','9'));
shuffle($possible_chars);
$string = substr(implode($possible_chars),0,5);
$_SESSION['captcha_string']=$string;
?>
<img src="captcha_generator.php" alt="Weinerdog!" />
and this is the bit from the second file where I try to grab the $string (captcha_string), which is named "captcha_generator.php:
<?php
session_start();
putenv('GDFONTPATH=' . realpath('.'));
header("Content-type: image/png");
//import string for the captcha from $_SESSION
$string = $_SESSION['captcha_string'];
// Build an image resource using an existing image as a starting point.
$backgroundimage = "captcha_wiener.jpg";
$im=imagecreatefromjpeg($backgroundimage);
$colour = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
// Output the string of characters using a true type font.
// Above we set the font path to the current directory, this
// means that arial.ttf font file must be in this directory.
$font = 'arial.ttf';
$angle = rand(-5,5);
imagettftext($im, 120, $angle, 50, 250, $colour, $font, $string);
// Draw some annoying lines across the image.
imagesetthickness($im, 10);
for ($i = 0; $i <3; $i++) {
imageline($im, rand(100,50), rand(150,200), rand(450,550), rand(200,250), $colour);
}
// Output the image as a PNG and the free the used memory.
imagejpeg($im);
imagedestroy($im);
?>
This is, of course, strictly an exercise to make sure we can pass values using session. There is no problem with the rest of the code making the captcha, it has been tested and works.
You're echo-ing some values with a content-type set to image/png, hence either you'll have the error of headers already sent, or, if the text wasn't sent yet (because cached by PHP), you'll have a broken image and you won't be able to see the text.
Don't worry, it has happened to everyone including me :-)
i wrote this code:
class Generate{
private $canvas;
function __construct($width, $height){
$this->canvas = imagecreatetruecolor($width, $height);
}
public function bg($r=0,$g=0,$b=0){
$color = imagecolorallocate($this->canvas, $r, $g, $b);
imagefill($this->canvas, 0, 0, $color);
}
public function gen(){
header('Content-Type: image/png');
imagepng($this->canvas, NULL, 9);
imagedestroy($this->canvas);
}
}
and called it with this:
$G = new Generate(100, 100);
$G->bg(255, 255, 255);
$G->gen();
its generating image fine when i comment out the header in the gen() function and set it to save the image. Like this:
imagepng($this->canvas, 'img.png', 9);
but i want it to send the header(output the image) but it gives me an error. can someone please tell me what i'm doing wrong? can you even send headers with-in a PHP class?
this code works fine when i don't use OOP
The answer to your question is yes, you can. You can send headers at any time before you send any output to the client, which I suspect is what your issue is.
You can also check the encoding that you're saving your file in. If you are saving your file as UTF-8, make sure you save it without a byte order mark. This counts as output, and will always be the first character in your file meaning any call to header() will generate a warning.
The code works perfectly for me when I run it as you posted it; are you sure that you aren't just losing your 100x100 white image on a white background? Try changing the color to, say, 127,255,255 (a lovely aqua) and see if it shows up.
$imageurl = "kaptka.gif";
$im = imagecreatefromgif($imageurl);
$b = imagecolorallocate($im, 0, 0, 0);
imagesetpixel($im, 5, 5, $b);
header('Content-Type: image/gif');
imagegif($im, "asd.gif");
kaptka.gif is normal gif image. I want to draw some pixels anywhere on the image. Asd.gif looks normal, but when i open the file it should show me both like asd.gif, but it shows just "IMAGE" text.
You are calling the function imagegif() with a filename. This will write the image to disc. To display the contents, simply call it without the filename: this will pass the contents to the output stream, which means it will be sent to the client's browser. One way to do both is to call it twice, once to save the file, and once to display it.
When saving the file, you can assign the result to a variable $foo=imagegif($im, 'bar.gif') and then check the result to see if the save was successful. A FALSE means it failed.
You say the image saved to the server is OK, so the reason you are getting an "IMAGE text" in your browser is probably because you are sending a PNG header, but no data (because of the way you called imagefig()).
I've got the following function that generates and saves an image based a text parameter. How can I call this in my file? I tried
INCLUDE 'outPrice.php';
to link to the external PHP and called it with this command,
outPrice($text);
To which I got the following response.
Warning: Cannot modify header information - headers already sent
Any help would be appreciated.
function outPrice($textval){
$textcolor = '666666';
$font="bgtbt.ttf";
$size = 20;
$padding= 1;
$bgcolor= "ffffff";
$transparent = 0;
$antialias = 0;
$fontfile = $fontpath.$font;
$box= imageftbbox( $size, 0, $fontfile, $textval, array());
$boxwidth= $box[4];
$boxheight= abs($box[3]) + abs($box[5]);
$width= $boxwidth + ($padding*2) + 1;
$height= $boxheight + ($padding) + 0;
$textx= $padding;
$texty= ($boxheight - abs($box[3])) + $padding;
// create the image
$png= imagecreate($width, $height);
$color = str_replace("#","",$bgcolor);
$red = hexdec(substr($bgcolor,0,2));
$green = hexdec(substr($bgcolor,2,2));
$blue = hexdec(substr($bgcolor,4,2));
$bg = imagecolorallocate($png, $red, $green, $blue);
$color = str_replace("#","",$textcolor);
$red = hexdec(substr($textcolor,0,2));
$green = hexdec(substr($textcolor,2,2));
$blue = hexdec(substr($textcolor,4,2));
$tx = imagecolorallocate($png, $red, $green, $blue);
imagettftext( $png, $size, 0, $textx, $texty, $tx, $fontfile, $textval );
header("content-type: image/jpeg");
imagejpeg($png, "price".$textval.".jpg");
imagedestroy($png);
}
How are you invoking this file? If you are calling it inside of an <img> tag, or from a CSS directive, then do as C. Walsh says and check for whitespace in the file (tip: for binary data, don't include a closing ?> tag in your script) as well as a Byte Order Mark at the beginning of your file (use a HEX editor like PSPad for this).
You may also want to consider, since errors may occur during your image script's execution, wrapping the script contents in ob_start() and ob_end_clean(), where ob_end_clean() is called just before the headers are sent and the image is generated.
If you are invoking it directly from the file in which you wish to embed the image, then use the following HTML scheme:
<img src="data:image/png;base64,DATADATADATA" alt ="" />
Where DATADATADATA is the base64 encoded version of your image.
See:
Data URI Scheme
PHP Manual Entry for base64_encode()
The message means that the page has already sent some data to the browser – if you don’t think this should have happened then it could be some whitespace somewhere in your PHP files. You’ll need to find where it’s coming from and remove it.
If it does turn out to be whitespace then this thread might be helpful.
Using the header() function (third last line) after any content has been sent as response, is not possible, because headers need to be sent first in all http communications. Make sure that your php files don't have whitespace before <?php or after ?>
The error you're getting is caused by output being sent to the browser before you call "header" near the end of the function.
Chances are you've got some white space sitting outside of your first and last <?php ?> tags. When this happens, PHP automagically sends headers to the browser indicating that you're outputting an HTML document. Once this has happened, you can no longer alter the headers, and PHP issues an error.
Track down where the output is coming from; try viewing the source of the document, and making sure you have no leading/trailing whitespace in the files that are included.