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();
?>
Related
I want to implement a simple captcha in ci4, I try to search a sample code in google and then copas it. But when run the code get result like this. Please help what wrong in my code ?
My controller is :
private function captcha()
{
$i = 0;
$imgHeight = 80;
$imgWidth = 250;
$randTotal = 7;
$randomDots = 50;
$randomLines = 25;
$font = realpath('./fonts/monofont.ttf');
$random = '';
$captTextColor = "0x142864";
$noiseColor = "0x142864";
$fontSize = $imgHeight * 0.65;
$random = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0,
$randTotal);
$image = #imagecreate($imgWidth, $imgHeight);
$arrTextColor = $this->hexToRGB($captTextColor);
$arrNoiseColor = $this->hexToRGB($noiseColor);
$bgColor = imagecolorallocate($image, 255, 255, 255);
$captTextColor = imagecolorallocate($image, $arrTextColor['red'], $arrTextColor['green'], $arrTextColor['blue']);
$imgNoiseColor = imagecolorallocate($image, $arrNoiseColor['red'], $arrNoiseColor['green'], $arrNoiseColor['blue']);
// Cetak titik acak di latar belakang gambar
for ($i = 0; $i < $randomDots; $i++) {
imagefilledellipse($image, mt_rand(0, $imgWidth), mt_rand(0, $imgHeight), 2, 3, $imgNoiseColor);
}
// Cetak garis acak di latar belakang gambar
for ($i = 0; $i < $randomLines; $i++) {
imageline(
$image,
mt_rand(0, $imgWidth),
mt_rand(0, $imgHeight),
mt_rand(0, $imgWidth),
mt_rand(0, $imgHeight),
$imgNoiseColor
);
}
// Cetak kotak teks dan tambahkan 6 kode huruf captcha
$textBox = imagettfbbox($fontSize, 0, $font, $random);
$x = ($imgWidth - $textBox[4]) / 2;
$y = ($imgHeight - $textBox[5]) / 2;
$_SESSION['captcha'] = $random;
// imagettftext($image, $fontSize, 0, $x, $y, $captTextColor, $font, $random);
imagettftext($image, $fontSize, 0, $x, $y, $captTextColor, $font, $random);
header('Content-Type: image/jpeg');
imagejpeg($image, null, null);
imagedestroy($image);
}
Thank you
Thank you.
Try adding the exit; command after the imagedestroy($image); line
I need to iterate through all pixels in an image to replace all but one color with black so that I can define all regions of a particular color. The code below is not working, the image remains unchanged. What am I doing wrong?
header('Content-Type: image/jpeg');
// open an image
$im = imagecreatefromjpeg('sunset.jpg');
$x_val = imagesx($im);
$y_val = imagesy($im);
$black = imagecolorallocate($im, 0, 0, 0);
for ($i = 0; $i < $x_val; $i++) {
$color_index = imagecolorat($im, $i, $i);
$colourarray = imagecolorsforindex($im, $color_index);
if ($colourarray[0] != 170 && $colourarray[1] != 0 && $colourarray[2] != 0) {
$color_index = imagecolorat($im, $i, $i);
imagecolorset($im, $color_index, 0, 0, 0);
} else {
$color_index = imagecolorat($im, $i, $i);
imagecolorset($im, $color_index, 170, 0, 0);
}
}
imagejpeg($im);
imagedestroy($im);
As the title says is there a max amount of objects you can draw using the GD library in PHP. Given the code below i can only get about 140 squares to appear. The line and square at the bottom only show if you don't max out the grid first. Anyone know of another way to get this done?
<?php
header('Content-type: image/png');
$png_image = imagecreate(3000, 3000);
imagecolorallocate($png_image, 15, 142, 210);
$gridx = 100;
$gridy = 100;
$count = 0;
$currentx = 0;
$currenty = 0;
function makeRec($xpos, $ypos, $c1, $c2, $c3) {
global $png_image, $currentx, $currenty;
imagefilledrectangle($png_image, $xpos, $ypos, $xpos+10, $ypos+10, imagecolorallocate($png_image, $c1, $c2, $c3));
$currentx = $xpos+11;
}
function makexLine($xpos, $ypos) {
global $png_image, $currentx, $currenty;
imageline($png_image, $xpos, $ypos, $xpos, $ypos+10, imagecolorallocate($png_image, 0, 0, 0));
$currentx = $xpos+1;
}
function makeyLine($xpos, $ypos) {
global $png_image, $currentx, $currenty;
imageline($png_image, $xpos, $ypos, $xpos+100, $ypos, imagecolorallocate($png_image, 0, 0, 0));
$currenty = $ypos+1;
}
for($y = 0; $y < $gridy; $y++) {
makeyline($currentx, $currenty);
for($x = 0; $x < $gridx; $x++) {
makexLine($currentx, $currenty);
if($count == 0) {
makeRec($currentx, $currenty, 255, 1, 255);
$count++;
}
else {
makeRec($currentx, $currenty, 255, 255, 255);
$count = 0;
}
}
makexLine($currentx, $currenty);
$currentx = 0;
$currenty = $currenty + 11;
}
makeyline(0, 200);
makeRec(200, 200, 255, 1, 255);
imagepng($png_image);
imagedestroy($png_image);
?>
Running a test script on my system that draws 1 million squares with imagefilledrectangle() in a chessboard pattern works fine (and surprisingly quickly). If there is a draw limit it's at least that high.
Your problem seems to be too many calls to imagecolorallocate(). Below I've modified your code to call imagecolorallocate() only once per colour:
header('Content-type: image/png');
$png_image = imagecreate(3000, 3000);
imagecolorallocate($png_image, 15, 142, 210);
$magenta = imagecolorallocate($png_image, 255, 1, 255);
$black = imagecolorallocate($png_image, 0, 0, 0);
$white = imagecolorallocate($png_image, 255, 255, 255);
$gridx = 100;
$gridy = 100;
$count = 0;
$currentx = 0;
$currenty = 0;
function makeRec($xpos, $ypos, $colour) {
global $png_image, $currentx, $currenty;
imagefilledrectangle($png_image, $xpos, $ypos, $xpos+10, $ypos+10, $colour);
$currentx = $xpos+11;
}
function makexLine($xpos, $ypos, $colour) {
global $png_image, $currentx, $currenty;
imageline($png_image, $xpos, $ypos, $xpos, $ypos+10, $colour);
$currentx = $xpos+1;
}
function makeyLine($xpos, $ypos, $colour) {
global $png_image, $currentx, $currenty;
imageline($png_image, $xpos, $ypos, $xpos+100, $ypos, $colour);
$currenty = $ypos+1;
}
for($y = 0; $y < $gridy; $y++) {
makeyline($currentx, $currenty, $black);
for($x = 0; $x < $gridx; $x++) {
makexLine($currentx, $currenty, $black);
if($count == 0) {
makeRec($currentx, $currenty, $magenta);
$count++;
}
else {
makeRec($currentx, $currenty, $white);
$count = 0;
}
}
makexLine($currentx, $currenty, $black);
$currentx = 0;
$currenty = $currenty + 11;
}
makeyline(0, 200, $black);
makeRec(200, 200, $magenta);
imagepng($png_image);
imagedestroy($png_image);
I am trying to copy image (to $img) after rotating image (many images $im) but I get weird behavior. Once I un-comment the line //$img = I only get the rotated image on my final output. Can I rotate the inner $im and copy it to final image$img?
<?php
$height = 80;
$width = 300;
$img = imagecreate($width, $height);
$c = imagecolorallocate ($img , 135, 135, 135);
imagefill($img, 0, 0, imagecolorallocate($img, 255, 255, 255));
for($i=0; $i<=5; $i++){
$im = imagecreatetruecolor(35, 35);
$gry = imagecolorallocate($im, 135, 135, 135);
$wht = imagecolorallocate($im, 255, 255, 255);
$j = mt_rand(0, 1);
$ch = mt_rand(0,1)?chr(rand(65, 90)):chr(rand(97, 122));
if($j == 0){
imagefill($im, 0, 0, $wht);
imagefttext($im, 20, 0, 3, 21, $gry, 'AHGBold.ttf', $ch);
//$img = imagerotate($im, mt_rand(0,10)-5, $wht);
}else{
imagefill($im, 0, 0, $gry);
imagefttext($im, 20, 0, 3, 21, $wht, 'AHGBold.ttf', $ch);
//$img = imagerotate($im, mt_rand(0,10)-5, $gry);
}
imagecopyresampled($img, $im, 5 + $i*42, $height/2 - 12, 0, 0, 40, 40, 25, 25);
}
header('Content-type: image/png');
imagepng($img);
change
$img = imagerotate($im, mt_rand(0,10)-5, $wht);
and
$img = imagerotate($im, mt_rand(0,10)-5, $gry);
to
$im = imagerotate($im, mt_rand(0,10)-5, $wht);
and
$im = imagerotate($im, mt_rand(0,10)-5, $gry);
in cases that imagerotes does not work you can use the following function to rotate an image:
function imagerotateEquivalent(&$srcImg, $angle, $bgcolor, $ignore_transparent = 0)
{
$srcw = imagesx($srcImg);
$srch = imagesy($srcImg);
if($angle == 0) return $srcImg;
// Convert the angle to radians
$theta = deg2rad ($angle);
// Calculate the width of the destination image.
$temp = array ( rotateX(0, 0, 0-$theta),
rotateX($srcw, 0, 0-$theta),
rotateX(0, $srch, 0-$theta),
rotateX($srcw, $srch, 0-$theta)
);
$minX = floor(min($temp));
$maxX = ceil(max($temp));
$width = $maxX - $minX;
// Calculate the height of the destination image.
$temp = array ( rotateY(0, 0, 0-$theta),
rotateY($srcw, 0, 0-$theta),
rotateY(0, $srch, 0-$theta),
rotateY($srcw, $srch, 0-$theta)
);
$minY = floor(min($temp));
$maxY = ceil(max($temp));
$height = $maxY - $minY;
$destimg = imagecreatetruecolor($width, $height);
imagefill($destimg, 0, 0, imagecolorallocate($destimg, 0,255, 0));
// sets all pixels in the new image
for($x=$minX;$x<$maxX;$x++) {
for($y=$minY;$y<$maxY;$y++)
{
// fetch corresponding pixel from the source image
$srcX = round(rotateX($x, $y, $theta));
$srcY = round(rotateY($x, $y, $theta));
if($srcX >= 0 && $srcX < $srcw && $srcY >= 0 && $srcY < $srch)
{
$color = imagecolorat($srcImg, $srcX, $srcY );
}
else
{
$color = $bgcolor;
}
imagesetpixel($destimg, $x-$minX, $y-$minY, $color);
}
}
return $destimg;
}
function rotateX($x, $y, $theta){
return $x * cos($theta) - $y * sin($theta);
}
function rotateY($x, $y, $theta){
return $x * sin($theta) + $y * cos($theta);
}
I got the above code from a note in php.net
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.