I have a site which displays a dynamically generated GD image (data pulled from SQL). I need to view this image to pinpoint inconsistencies in my coding. These aren't errors, but rather just simple variables that are out of place that I must isolate. The easiest way I've found to do this is to simply echo the variables at different points in the code.
The problem is that the GD Image will overlay the page and so nothing is displayed from echo/print. The only way I can call the variables/functions the way I want to is by clicking on unique spots on this image. So the image must be there to echo the correct php variables. Both must be present at the same time. The only way I can echo/print is to turn off the image, but then these variables tell me nothing without being able to look at the image.
I don't want to use breakpoints/debugging etc as I'm on a shared host and don't have access to the extensions required for this, and I don't want to run a server locally for development.
I'm pulling the image in an img src="image.php" tag, and the PHP is stored in an external file called functions.php. The index.html which brings it all together is just jquery/javascript.
How can I echo the outputs with the GD image still displayed?
Output your debugging to the log.
error_log('Your message here...');
http://php.net/manual/en/function.error-log.php
You could buffer the output of the script using ob_start()/ob_get_contents() and then use imagestring to draw those logs on the image like so:
ob_start();
echo("Foo");
$out = ob_get_contents();
imagestring($image, 5, 0, 0, $out, imagecolorallocate($image, 255, 255, 255));
ob_end_clean();
Related
I'm fairly new to php but I'm trying to send an image to a buffer or some sort of temporary place where I can access later. The script I'm calling merges a bunch of images into one, then displays that image (see it in action here - change query parameters to change image). Here's a piece of my code so you have an idea of how that's happening:
$dest = imagecreatefrompng($img0);
$src12 = imagecreatefrompng($img12);
imagecolortransparent($src12, imagecolorat($src12, 0, 0));
//copy and merge
$src12_x = imagesx($src12);
$src12_y = imagesy($src12);
imagecopymerge($dest, $src12, 0, 0, 0, 0, $src12_x, $src12_y, 100);
// Output and free from memory
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
However, this is an external script so I'd like to be able to pull that image from another page. I'm not sure what the best way to do it is... temporarily store it or pass the image back through. The one constraint is that the image has to exist before the content of the parent page is loaded. How can I make this happen?
If I understand correctly what you mean;
1) You want to pull the image from another website and save it to disk, you can do this;
file_put_contents("img.png", file_get_contents("URL-TO-IMAGE"));
2) You want to just display it? As the URL aboves headers are to display an image, you can put it right into an IMG tag.
<img src="URL-TO-IMAGE">
I am trying to generate a PDF with an image that is also generated by php.
Sounds simple enough and I am sure I'm just screwing up the header but I can't seem to find a solution here.
first I generate a PDF:
define('FPDF_FONTPATH','fonts/');
require('scpt/fpdf.php');
class PDF extends FPDF {}
$pdf = new FPDF('P','in',array(8.5,11));
$pdf->SetAutoPageBreak(false,0);
$pdf->SetTextColor(0,0,0);
$pdf->SetDrawColor(0,0,0);
$pdf->SetFont('Helvetica','',12);
$pdf->Image('label.php?imgid=17',0,0,0,0,'PNG');
$pdf->Output('label.pdf','D');
then I generate the PNG in label.php:
if(isset($_GET["imgid"])) {
header("Content-Type: image/png");
$im = #imagecreate(110, 20)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 0, 0, 0);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, "A Simple Text String", $text_color);
imagepng($im);
imagedestroy($im);
}
This will output: FPDF error: Not a PNG file:....
calling label.php?imgid=17 in the browser however will show me the image just fine...
What am I missing?
EDIT
In document:
Example
// Insert a logo in the top-left corner at 300 dpi
$pdf->Image('logo.png',10,10,-300);
// Insert a dynamic image from a URL
$pdf->Image('http://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World',60,30,90,0,'PNG');
so it SHOULD be possible to include a dynamically generated image without saving it first?!
EDIT #2
I made it work with the library mem_image but the problem remains that this should not throw an error IMO?! So I leave this question open to see if there is indeed something wrong with my script of this turning out to be a bug.
You almost had it, you're missing only a couple things. First you need the full server address in the URL for your Image() call, so instead of
$pdf->Image('label.php?imgid=17',0,0,0,0,'PNG');
You need:
$pdf->Image('http://www.yourserver.com/label.php?imgid=17',0,0,0,0,'PNG');
That will eliminate the FPDF error you were encountering. Then to get FPDF to render your output correctly, you need to add a call to AddPage(), so your PDF generation script would become:
require('scpt/fpdf.php');
$pdf = new FPDF('P','in',array(8.5,11));
$pdf->AddPage();
$pdf->Image('http://www.yourserver.com/label.php?imgid=17',0,0,0,0,'PNG');
$pdf->Output('label.pdf','D');
Of course you don't need the SetTextColor(), SetFont(), etc if you're only including the single image. You didn't need the custom class definition either (I removed the unneeded lines).
Don't forget to substitute www.yourserver.com for the appropriate domain and path for your script.
The argument to the Image function needs to be a file, not a URL or another script. Since you already have your label script, the easiest work around would be to download the image to a temp location and then call $pdf->Image() with that temporary file.
This problem occurred With your file name,Make sure your passing file name is valid
function _parsepngstream($f, $file)
{
// Check signature
if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
$this->Error('Not a PNG file: '.$file);
...
}
View allow_url_fopen directive
http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
You need to do only changes that
require('fpdf.php');
and do the
$pdf->Image('http://www.yourserver.com/label.php?imgid=17',0,0,0,0,'PNG');
and run your code...
First, try to check your url with this code
$handle = fopen("http://www.yourserver.com/label.php?imgid=17", "rb");
print_r(fread($handle, 8192));
you with see what the contain in your url
**) make sure your url is not redirect to the login page
much more easy, only put .png in the final of dinamic chain and its all
example:
$pdf->Image('http://www.yourserver.com/label.php? imgid=17.png',0,0,0,0,'PNG');
or
$pdf->Image('../label.php?imgid=17.png',0,0,0,0,'PNG');
the mime type is not recognized in the url why does not appear png, if it's a stupid mistake but it is proven, google does the same by adding the extension with the url & PNG
$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()).
Inclusion in HTML or CSS using PHP
http://en.wikipedia.org/wiki/Data_URI_scheme#Inclusion_in_HTML_or_CSS_using_PHP
I have to hide the source of my images, to avoid someone from copying down the entire folder.
I tried using IONCUBE before, but now I want simpler implementation.
Again, I want to know generated HTML page source obfuscation techniques not the obfuscation of PHP files.
EDIT:
I want this part of code in the generated HTML page to be obfuscated.
<div id="ImgHolder">
<img src="./images/blank.gif" id="FullSizeImageTail"/>
<img src="http://blah.blahblah.edu/random/<?=$_GET['random']?>/<?=$_GET['random2']?>" id="FullSizeImage"/>
</div>
Obfuscating HTML code is completely pointless. There's no such thing as clever HTML code, and no one cares what your HTML code is.
The meaning of the code that you want to obfuscate in your question will still be very obvious after obfuscation anyway.
Consider the code that you want to obfuscate:
<div id="ImgHolder">
<img src="./images/blank.gif" id="FullSizeImageTail"/>
<img src="http://blah.blahblah.edu/random/<?=$_GET['random']?>/<?=$_GET['random2']?>" id="FullSizeImage"/>
</div>
Well, all of the HTML symbols have to remain. That means you cant change "div", "img", "src", "id", etc.
All you can change are "ImgHolder", "FullSizeImageTail" and "FullSizeImage".
The addresses of images and so on must remain.
So your code visible to users of your website might become:
<div id="a"><img src="./images/blank.gif" id="b"/><img src="http://blah.blahblah.edu/random/123/456" id="c"/></div>
Did that really hide anything?
You can write a quick little PHP script that does the image loading. You can put this process script in a directory segregated from all the images and then link to it like this:
<img src="http://blah.blahblah.edu/path/to/scripts/image.php" id="c" />
And the image.php file would look something like this:
$file = '/path/to/yourimage.png';
$size = getimagesize($file);
$type = $size['mime'];
header('Content-type: '.$type);
print file_get_contents($file);
exit;
You could of course supply variables to the image.php and do logic in the image.php file to get specific files.
For example:
<img src="http://blah.blahblah.edu/path/to/scripts/image.php?n=<?=base64_encode('my_image.png')?>" id="c" />
PHP checking for $_GET variable:
if(isset($_GET['n'])) {
$file = '/path/to/'.base64_decode($_GET['n']);
if(file_exists($file)) {
$size = getimagesize($file);
$type = $size['mime'];
header('Content-type: '.$type);
print file_get_contents($file);
exit;
}
}
EDIT: I read in another comment your worried about registered users downloading your paintings. You can also prevent hotlinking (if that's something that interests you as well) by including this in the image.php file at the top.
//Don't allow hotlinking
$referer = explode("/", $_SERVER['HTTP_REFERER']);
if($referer[2] != "blah.blahblah.edu") {
$my_img = imagecreate(265, 90);
$background = imagecolorallocate($my_img, 0, 0, 255);
$text_color = imagecolorallocate($my_img, 255, 255, 0);
$line_color = imagecolorallocate($my_img, 128, 255, 0);
imagestring($my_img, 4, 30, 25, "Hot Linking Not Permitted", $text_color);
imagestring($my_img, 4, 30, 50, "blah.blahblah.edu", $text_color);
imagesetthickness($my_img, 5);
imageline($my_img, 30, 45, 230, 45, $line_color);
header("Content-type: image/jpeg");
imagejpeg($my_img);
exit;
}
You can't have the actual page markup be base64-encoded. The Wikipedia article you linked is about data URIs — that is, you can include them on a page where a URI is expected. This does include an <a> tag, but that will only allow you to include the linked page inline in the same file. In browsers that support using a data URI that way, once you've navigated to the page in the data link, the source code will show in plaintext. It doesn't obfuscate the source any more than a normal link does. Ditto for iframes.
And even if you could do this, the warnings about how useless obfuscation is still apply. Base64-encoding in particular is really bad obfuscation, because it's intentionally reversible just by typing "decode base64" into Google.
If you want to gain some level of protection against somebody downloading all your images without requiring authorization and authentication, your best bet would be to use an algorithm that generates complex and unpredictable names for the image files and turn off the directory index page. Then they could only download the images you explicitly send to them without a lot of brute-forcing.
The pointlessness part comes from the idea that you have them wide open on the web anyway, so they are there. But it really seems like you just want clients to not get them all at once. This might be achived by 1) deny directory listing and; 2) using a different naming scheme for your images which reduces automated guessing.
This approach differs from Michael's answer in that this is less exploitable. anything with a simple numeric naming convention implies a sequential naming convention and sequential names are easy to generate.
Why not make the directory so that it does not list the contents of it.
"If you create a new directory (or folder) on your website, and do not put a "index.html" file in it, you may be surprised to find that your visitors can get a directory listing of all the files in that folder. For example, if you create a folder called "incoming", you can see everything in that directory simply by typing "http://www.example.com/incoming/" in your browser. No password or anything is needed." - http://www.thesitewizard.com/apache/prevent-directory-listing-htaccess.shtml
I would like to generate a dynamic image from a script, and then have it load to the browser without being persistent on the server.
However, I cannot call this by setting the image's src="script.php", since that would require running the script that just generated the page and its data all over again, just to get the final data that will generate the graph.
Is there a way to do this that is similar to setting image's src="script.php", but which is called from within another script, and just sends the image without saving it? I need access to the data that is used in the generation of the markup, in order to create this dynamic image.
Or, if not, what is the easiest way to destroy the image once the page is loaded? a quick ajax call?
Is there any way to cache certain data for some limited time frame in order for it to be available to some other script?
Any ideas would be greatly appreciated, as I'm having a really hard time finding the right solution to this...
Thanks!
You can inline the image into a <img> tag if you need to.
Like
<?php
$final_image_data; // Your image data, generated by GD
$base64_data = base64_encode($final_image_data);
echo "<img src=\"data:image/png;base64,{$base64_data}\" ... />";
?>
That should work on all modern browsers, and IE8. Doesn't work well with some email clients tho (Outlook, for one).
Also, another solution I found is to store the image in a session variable which is then called from a php script in the image tag. This would allow a user specific image to be served, and then removed from memory by the script... This also avoids messy img src="" tags...
Hopefully that is helpful to someone.
Use a rewrite rule.
RewriteRule ^magicimage.jpg$ /myscript.php
Then simply echo your image data from gd, instead of writing it to disk -- which is as simple as not providing a filename to the appropriate image*() function
myscript.php
<?php
$im = imagecreatetruecolor($w, $h);
//...do gd stuff...
header('Content-type: image/jpeg');
//this outputs the content directly to the browser
//without creating a temporary file or anything
imagejpeg($im);
And finally, utilize the above
display.php
<img src="magicimage.jpg">