Related
I'm working on a project in DRUPAL and am trying to programatically add an image to an existing pdf - an "Approved" image for invoices. I've Frankensteined the code from the StackExchange post - How can I add a watermark to an existing PDF file using PHP? - and have managed to get it working outside of Drupal (7.0) but once I port the code over, I get nothing, no errors, no warnings, nadda .... Just wondering if someone out there can help me on this issue, it been driving me nuts for a bit now .... Sorry about the sloppy code....
<?php
global $user;
ob_start();
$filename ="approved_".$user->name.".png";
$file = "2pages.pdf";
$op = 100;
////////////////////////////////////////////////////////////////////////////
require('fpdf.php');
require('fpdi.php');
$text = "Text message for watermark goes here";
$name = uniqid();
$font_size = 5;
$ts=explode("\n",$text);
$width=0;
foreach ($ts as $k=>$string) {
$width=max($width,strlen($string));
}
$width = imagefontwidth($font_size)*$width;
$height = imagefontheight($font_size)*count($ts);
$el=imagefontheight($font_size);
$em=imagefontwidth($font_size);
$img = imagecreatetruecolor($width,$height);
// Background color
$bg = imagecolorallocate($img, 255, 255, 255);
imagefilledrectangle($img, 0, 0,$width ,$height , $bg);
// Font color
$color = imagecolorallocate($img, 0, 0, 0);
foreach ($ts as $k=>$string) {
$len = strlen($string);
$ypos = 0;
for($i=0;$i<$len;$i++){
$xpos = $i * $em;
$ypos = $k * $el;
imagechar($img, $font_size, $xpos, $ypos, $string, $color);
$string = substr($string, 1);
}
}
imagecolortransparent($img, $bg);
$blank = imagecreatetruecolor($width, $height);
$tbg = imagecolorallocate($blank, 255, 255, 255);
imagefilledrectangle($blank, 0, 0,$width ,$height , $tbg);
imagecolortransparent($blank, $tbg);
if ( ($op < 0) OR ($op >100) ){
$op = 100;
}
imagecopymerge($blank, $img, 0, 0, 0, 0, $width, $height, $op);
$pdf = new FPDI();
//********************************************************************
if (file_exists($file)){
$pagecount = $pdf->setSourceFile($file);
} else {
return FALSE;
}
/////////////////////////////////////////
for($i=1; $i <= $pagecount; $i++) {
$tpl = $pdf->importPage($i);
$pdf->addPage();
$pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);
//Put the watermark
$pdf->Image($filename, 0, 0, 40, 25, 'png');}
/////////////////////////////////////////
return $pdf->Output('test10.pdf', 'F');
////////////////////////////////////////////////////////////////////////////
ob_end_flush();
?>
Of note, I am also open you anyone who may have an alternate method to achieve the same end result
thanks in advance!
So after taking some advise from Marc B, I went through the code and isolated the issue. For those looking for the answer to this question, here's the solution I came up with ... Hope it helps!
<?php
ob_start();
function PlaceWatermark($file, $text, $xxx, $yyy, $op, $outdir) {
global $user;
require('fpdf.php');
require('fpdi.php');
$myfilename = 'approved_'.$user->name.'.png';
// Created Watermark Image
$pdf = new FPDI();
//if (file_exists("./".$file)){
$pagecount = $pdf->setSourceFile($file);
//} else {
// return FALSE;
//}
/////////////////////////////////////////
for($i=1; $i <= $pagecount; $i++) {
$tpl = $pdf->importPage($i);
$pdf->addPage();
$pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);
//Put the watermark
if (file_exists($myfilename)) {
$pdf->Image($myfilename, 0, 0, 40, 25, 'png');
} else {
$pdf->Image('approved.png', 0, 0, 40, 25, 'png');
}
}
/////////////////////////////////////////
return $pdf->Output('test_output.pdf', 'F');
}
PlaceWatermark("Original.pdf", "", 30, 120, 100,TRUE);
ob_end_flush();
?>
I was hoping to get in touch with someone on a situation that I cannot find the solution to anywhere.
I am trying to create a captcha on my website using php and although I was able to create an image and create the random captcha text.
I am unable to over lay the two. Here is my code:
<?PHP
session_start();
function generateRandomString($length = 10) {
$letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$len = strlen($letters);
$letter = $letters[rand(0, $len - 1)];
$text_color = imagecolorallocate($image, 0, 0, 0);
$word = "";
for ($i = 0; $i < 6; $i++) {
$letter = $letters[rand(0, $len - 1)];
imagestring($image, 7, 5 + ($i * 30), 20, $letter, $text_color);
$word .= $letter;
}
$_SESSION['captcha_string'] = $word;
}
function security_image(){
// $code = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : generate_code();
//$font = 'content/fonts/comic.ttf';
$width = '110';
$height = '20';
$font_size = $height * 0.75;
// $image = #imagecreate($width, $height) or die('GD not installed');
global $image;
$image = imagecreatetruecolor($width, $height) or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($image, 255, 255, 255);
imagefilledrectangle($image,0,0,200,50,$background_color);
$line_color = imagecolorallocate($image, 64,64,64);
for($i=0;$i<10;$i++) {
imageline($image,0,rand()%50,200,rand()%50,$line_color);
}
$pixel_color = imagecolorallocate($image, 0,0,255);
for($i=0;$i<1000;$i++) {
imagesetpixel($image,rand()%200,rand()%50,$pixel_color);
}
//$textbox = imagettfbbox($font_size, 0, $font, $code);
//$textbox = imagettfbbox($font_size, 0, $randomString);
$x = ($width - $textbox[4]) / 2;
$y = ($height - $textbox[5]) / 2;
// imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $code);
imagettftext($image, $font_size, 0, $x, $y, $text_color , $word);
$images = glob("*.png");
foreach ($images as $image_to_delete) {
#unlink($image_to_delete);
}
imagepng($image, "image" . $_SESSION['count'] . ".png");
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
}
security_image();
?>
I have no idea what I’m doing wrong. I’ve spent over 10 hours on this “display text” issue. I don’t understand and I am desperate for help. I even downloaded working captcha version from other resources that break once I upload it to my server. I have no idea whats going on. At first I thought there was something wrong with my server but the fact that I can even create the pixels, lines image means that it is at least working.
Please help!!!!
UPDATE---------------------------------------------
Thank you for your suggestions. Here is the edited code. I'm still getting the same issue.
<?PHP
session_start();
function security_image(){
global $image;
// $code = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : generate_code();
$font = 'content/fonts/comic.ttf';
$width = '110';
$height = '20';
$font_size = $height * 0.75;
$image = imagecreatetruecolor($width, $height) or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($image, 255, 255, 255);
imagefilledrectangle($image,0,0,200,50,$background_color);
$line_color = imagecolorallocate($image, 64,64,64);
for($i=0;$i<10;$i++) {
imageline($image,0,rand()%50,200,rand()%50,$line_color);
}
$pixel_color = imagecolorallocate($image, 0,0,255);
for($i=0;$i<1000;$i++) {
imagesetpixel($image,rand()%200,rand()%50,$pixel_color);
}
$letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$len = strlen($letters);
$letter = $letters[rand(0, $len - 1)];
$text_color = imagecolorallocate($image, 0, 0, 0);
$word = "";
for ($i = 0; $i < 6; $i++) {
$letter = $letters[rand(0, $len - 1)];
imagestring($image, 7, 5 + ($i * 30), 20, $letter, $text_color);
$word .= $letter;
}
$_SESSION['captcha_string'] = $word;
/*texbox unitinitialized (removed for the sake of just showing the word size doesnt matter)
$x = ($width - $textbox[4]) / 2;
$y = ($height - $textbox[5]) / 2;
*/
$x = ($width) / 2;
$y = ($height) / 2;
imagettftext($image,$font, 4, $x, $y, $word);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
}
security_image();?>
i made some suggested changes but the code seems to still do the same thing. Just display the lines and pixels as expected but the text still is missing... ?
There are some several "errors" in your functions, let's fix them:
In generateRandomString()
generateRandomString($length = 10)
$lenght is not used its scope.
$text_color = imagecolorallocate($image, 0, 0, 0);
$image is uninitialized
In security_image() function:
$textbox is uninitialized
$text_color and $word is uninitialized.
And Wrong parameter count for imagettftext() You add 7 parameters, and forget the font file parameter.
found the problem. using this:
http://php.net/manual/en/function.imagettftext.php
i was able to see that the font location was incorrect. using the example on that page and editing it to my needs worked.
Does any of you know how to add random letters aswel as random numbers.
thanks for you help.
<?php
session_start();
$image = imagecreate(, );
$bgcolor = imagecolorallocate($image, , ,);
$textcolor = imagecolorallocate($image, , , );
$code = rand(00, 99);
$_SESSION['code'] = ($code);
imagestring($image, , , , $code, $textcolor);
header ("Content-type: image/png");
imagepng($image);
?>
I always like to do this for random letters and numbers using md5. its not completely random, but it still returns a random string with both numbers and letters.
$i = rand(100000000, 9999999999)
$i = md5($i); //creates a hashed string with 32 characters
$i = str_split($i, 10); //10 is the amount of characters of your string max 32
$i = $i[0];
i have a function for it
function createRandomString() {
$chars = "abcdefghijkmnopqrstuvwxyz023456789";
srand((double)microtime()*1000000);
$i = 0;
$randomstring = '' ;
while ($i <= 7) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$randomstring = $randomstring . $tmp;
$i++;
}
return $randomstring;
}
echo createRandomString();
You could do something like this.
<?php
$code = substr(md5(microtime()),rand(0,26),10);
$im = imagecreate(100, 30);
$bg = imagecolorallocate($im, 255, 255, 255);
$textcolor = imagecolorallocate($im, 0, 0, 0);
imagestring($im, 5, 0, 0, $code, $textcolor);
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
Sources used:
https://stackoverflow.com/a/5438778/1978142
http://www.php.net//manual/en/function.imagestring.php
how can i validate if the user has enter the right captcha using ajax? and prevent the form submission if $_POST['captchainput'] != $_SESSION['code'].
this is the markup
<form action="captchaccept.php" method="POST" name="maincontact">
<input type="text" placeholder="Please enter the code" autocomplete="off" id="captchainput" name="captchainput">
<img src="captcha.php" id="captchaimage">
</form>
captcha.php
`
session_start();
$image_width = 135;
$image_height = 30;
$characters_on_image = 8;
$font = 'captchafont/acmesa.ttf';
$possible_letters = '23456789abcdfghjkmnpqrstvwxyz';
$random_dots = 10;
$random_lines = 30;
$captcha_text_color="0x142864";
$captcha_noice_color = "0x142864";
$code = '';
$i = 0;
while ($i < $characters_on_image) {
$code .= substr($possible_letters, mt_rand(0, strlen($possible_letters)-1), 1);
$i++;
}
$_SESSION['code'] = $code;
$font_size = 14;
$image = #imagecreate($image_width, $image_height);
$background_color = imagecolorallocate($image, 255, 255, 255);
$arr_text_color = hexrgb($captcha_text_color);
$text_color = imagecolorallocate($image, $arr_text_color['red'],
$arr_text_color['green'], $arr_text_color['blue']);
$arr_noice_color = hexrgb($captcha_noice_color);
$image_noise_color = imagecolorallocate($image, $arr_noice_color['red'],
$arr_noice_color['green'], $arr_noice_color['blue']);
for( $i=0; $i<$random_dots; $i++ ) {
imagefilledellipse($image, mt_rand(0,$image_width),
mt_rand(0,$image_height), 2, 3, $image_noise_color);
}
$textbox = imagettfbbox($font_size, 0, $font, $_SESSION['code']);
$x = ($image_width - $textbox[4])/2;
$y = ($image_height - $textbox[5])/2;
imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $_SESSION['code']);
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
function hexrgb ($hexstr) {
$int = hexdec($hexstr);
return array( "red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
}`
captchaaccept.php
`
session_start();
if(isset($_SESSION['code'])) {
if(empty($_POST['captchainput']) === false) {
if($_SESSION['code'] === $_POST['captchainput']) {
echo 'ok';
}
}
}`
can someone teach me how to use ajax validation for this captcha? or just show me an example , thanks in advance :)
Using jQuery you can do it like this:
(function($) {
$('#captchainput').on('submit', function(e) {
// Prevent the browser submitting the form
e.preventDefault();
// Put the form in variable form
var form = $(this);
// Do a AJAX post with the form data and check the response
$.post(form.attr('action'), form.serialize(), function(data) {
if(data === 'ok') {
// Captcha passed!
} else {
// Captcha failed!
}
});
});
})(jQuery);
Also in your code;
<form action="captchaccept.php" ... should be
<form action="captchaaccept.php" ... I think ;-)
Try this one also...
var posted_captcha = $( "#captchainput" ).val();
$.ajax({
url : 'captchaaccept.php',
data : 'captchainput=' + posted_captcha,
type : 'post',
success: function (res) {
if(res=='ok'){
alert('Validation pass');
}else{
alert('Validation fail');
}
}
});
i have this php program which takes in an angle as a get parameter and prints a segment of a circle with that angle:
<?php
$size = 600;
$img = imagecreatetruecolor($size, $size);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
imagefilledrectangle($img,0,0,$size,$size,$white);
function Vector($palette,$startx,$starty,$angle,$length,$colour){
$angle = deg2rad($angle);
$endx = $startx+cos($angle)*$length;
$endy = $starty-sin($angle)*$length;
return(imageline($palette,$startx,$starty,$endx,$endy,$colour));
}
$ang = 0;
while($ang <= $_GET['angle']){
Vector($img,$size/2,$size/2,$ang,200,$black);
$ang += 1;
}
header("Content-type: image/png");
imagepng($img);
?>
The function vector basically draws a line with the given parameters. So i loop through a number of times and then each time i loop through i increase the angle by 1. And then i call the vector function which basically draws a sort of circle segment with the specified angle.
But when i wish to draw another sector of the circle starting at the end point of the previous circle, it overlaps! By the way, here's the code:
<?php
$size = 600;
$img = imagecreatetruecolor($size, $size);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
$blue = imagecolorallocate($img, 0, 0, 255);
imagefilledrectangle($img,0,0,$size,$size,$white);
function Vector($palette,$startx,$starty,$angle,$length,$colour){
$angle = deg2rad($angle);
$endx = $startx+cos($angle)*$length;
$endy = $starty-sin($angle)*$length;
return(imageline($palette,$startx,$starty,$endx,$endy,$colour));
}
$int = 0;
while($int <= $_GET['angle']){
Vector($img,$size/2,$size/2,$int,200,$black);
$int += 0.01;
}
$int = 0;
while($int <= $_GET['angle']){
Vector($img,$size/2,$size/2,$int,200,$blue);
$int += 0.01;
}
header("Content-type: image/png");
imagepng($img);
?>
In the above code, i expect to draw a circle sector with an angle and then draw another sector with the same angle but in blue color.
I want the 2nd sector to start where the first sector ended, but it overlaps?
So how do i make it start where the previous one stopped?
You say, that you have a function to draw a vector with a certain angle right? Then you can have a loop 360 times and increase the angle by 1 degree per loop and draw the vector. You'll get a circle.
For a pie chart all you have to do is change colours at certain intervals depending upon your segment's angle...
If you're working on a voting system, here's the FULL source code for a PHP image generator which takes in n number of QueryString arguments and makes a pie chart with all those QueryString arguements and puts in a legend for them:
<?php
$size = 600;
$img = imagecreatetruecolor($size, $size);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
imagefilledrectangle($img,0,0,$size,$size,$white);
function Vector($palette,$startx,$starty,$angle,$length,$colour){
$angle = deg2rad($angle);
$endx = $startx+cos($angle)*$length;
$endy = $starty-sin($angle)*$length;
return(imageline($palette,$startx,$starty,$endx,$endy,$colour));
}
$sum__ = array_sum($_GET);
$items = array();
foreach($_GET as $key => $value){
$items[$key] = ($value/$sum__)*360;
}
$items2 = array();
$cur = 0;
foreach($items as $key => $value){
$cur += $value;
$items2[$key]=$cur;
}
$colors = array();
foreach($items as $key => $value){
while(array_key_exists($key,$colors) == False){
$tempcolor = imagecolorallocate($img, rand(0,255), rand(0,255), rand(0,255));
if(in_array($tempcolor,$colors) == False){
$colors[$key] = $tempcolor;
}
}
}
$int = 0;
foreach($items2 as $key => $value){
while($int <= $value){
Vector($img,$size/2,$size/2,$int,200,$colors[$key]);
$int += 0.01;
}
}
$container = 10;
foreach($items2 as $key => $value){
imagefilledrectangle($img, 4, $container, 50, $container+15, $colors[$key]);
imagestring($img,5,4+60,$container,$key,$black);
$container += 20;
}
header("Content-type: image/png");
imagepng($img);
?>
hope that helps...
Just FYI, you only need to change two lines of your original code to do what you want. Delete the second $int = 0; and make a change to the next line so that:
$int = 0;
while($int <= $_GET['angle']){
Vector($img,$size/2,$size/2,$int,200,$blue);
$int += 0.01;
}
Becomes:
//delete '$int = 0;'
while($int <= ($_GET['angle']) * 2){
Vector($img,$size/2,$size/2,$int,200,$blue);
$int += 0.01;
}
It's not a general solution but hopefully will allow you to see what you were originally doing wrong.