Repeating watermark php - php

I am using Intervention Image image manipulation library this library in a project and I am stuck on adding watermark image all over the source image.
Is it possible to repeat the watermark image on all over the source image like in the following example?
I try the following code, but it doesn't work for me.
$thumbnail = $manager->make($name);
$watermark = $manager->make($watermarkSource);
$x = 0;
while ($x < $thumbnail->width()) {
$y = 0;
while($y < $thumbnail->height()) {
$thumbnail->insert($watermarkSource, 'top-left', $x, $y);
$y += $watermark->height();
}
$x += $watermark->width();
}
$thumbnail->save($name, 80);

I've just solved this problem via Intervention Image library using it in Laravel Framework. So here's code snippet.
public function watermarkPhoto(String $originalFilePath,String $filePath2Save ){
$watermark_path='photos/watermark.png';
if(\File::exists($watermark_path)){
$watermarkImg=Image::make($watermark_path);
$img=Image::make($originalFilePath);
$wmarkWidth=$watermarkImg->width();
$wmarkHeight=$watermarkImg->height();
$imgWidth=$img->width();
$imgHeight=$img->height();
$x=0;
$y=0;
while($y<=$imgHeight){
$img->insert($watermark_path,'top-left',$x,$y);
$x+=$wmarkWidth;
if($x>=$imgWidth){
$x=0;
$y+=$wmarkHeight;
}
}
$img->save($filePath2Save);
$watermarkImg->destroy();
$img->destroy(); // to free memory in case you have a lot of images to be processed
}
return $filePath2Save;
}
If you use PHP version prior to 7 remove String type declaration from function arguments. just make it
public function watermarkPhoto($originalFilePath, $filePath2Save ){....}
Also if you are not using Laravel Framework and you don't have File class included just remove redundand check from function.
if(\File::exists($watermark_path))
So the simplest framework-agnostic function would be:
function watermarkPhoto($originalFilePath, $filePath2Save ){
$watermark_path='photos/watermark.png';
$watermarkImg=Image::make($watermark_path);
$img=Image::make($originalFilePath);
$wmarkWidth=$watermarkImg->width();
$wmarkHeight=$watermarkImg->height();
$imgWidth=$img->width();
$imgHeight=$img->height();
$x=0;
$y=0;
while($y<=$imgHeight){
$img->insert($watermark_path,'top-left',$x,$y);
$x+=$wmarkWidth;
if($x>=$imgWidth){
$x=0;
$y+=$wmarkHeight;
}
}
$img->save($filePath2Save);
$watermarkImg->destroy();
$img->destroy();
return $filePath2Save;
}
Also you need watermark image in png format with transparent background.

I'm just adding one thing added to your accepted answer when you try your code and the above-accepted code, the watermark on the images will be very close together and close together with what I tried. like this
So if you want the watermarks like what you want, you need to modify the code with plus numbers on wmarkheight and wmarkwidth like this:
while ($x < $imgWidth) {
$y = 0;
while($y < $imgHeight) {
$imgFileCollection->insert($watermark, 'top-left', $x, $y);
$y += $wmarkHeight+30;
}
$x += $wmarkWidth+40;
}
this line of code is important:
$y += $wmarkHeight+30;
$x += $wmarkWidth+40;
and you will get the result like that below:

Related

Convert PDF to PNG without transparent background

I use the following code to convert PDF to PNG. As you can see, I use code setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE ) to remove the background transparency. But in practice it only works for the last page. Do you think there is a problem with the code? Do you have a better solution with a higher speed?
$PDF = 'test.pdf';
$img = new imagick();
$img->readImage($PDF.'[0-9]'); //Convert 10 pages
$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE );
$pages = count($img);
$img->writeImages('./images/'.'pdf.png', true);
This looks like an iterator issue. You can try looping with something like this:
<?php
$PDF = 'test.pdf';
$img = new Imagick();
$img->readImage($PDF. '[0-9]'); //Convert 10 pages
$lastIndex = $img->getIteratorIndex();
$img->resetIterator();
for($i = $img->getIteratorIndex(); $i <= $lastIndex; $i++) {
$img->setIteratorIndex($i);
$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
}
$pages = count($img); // not sure why you need this
$img->writeImages('./images/'.'pdf.png', true);
You could also get the iterating part down to a simple loop, if you like it more, since the Imagick class implements Iterator:
foreach($img as $i)
{
$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
}

Error in mPDF Xref?

I am using the mpdf extension in my yii2 site in which the pdf are created.The pdf files are uploaded as an attachment first & then merged using the mpdf, this is working fine for the pdf files of version less than or equals to 1.4 & if i use a pdf file greater than this it gives me the error.I found the posts regarding this too but there is no actual answer its just asked to use the FPDI which also causes this error & i cannot chang my library to any other my whole work is dependent on this mpdf library.The users cannot save there file firstly in lower version & then upload it so please suggest me something i can do with it.
//merge multiple PDF files
$pdf=new mPDF('', 'Letter', 0, '', 8.5, 11);
$pdf->SetImportUse();
if($body !="")
{
$pdf->WriteHTML($body);
$pdf->WriteHTML('<pagebreak />');
}
$body1='<style>#page {margin: 96px;border:1px solid red;}</style>';
$fileArcount = count($multifileArr);
$z=1;
foreach($multifileArr as $fileAr)
{
if($fileAr !="")
{
$dashboard_pdf_file="../web/uploads/".$fileAr;
}
$pagecount = $pdf->SetSourceFile($dashboard_pdf_file);
for ($i=1; $i<=$pagecount; $i++) {
$import_page = $pdf->ImportPage($i);
$pdf->UseTemplate($import_page);
if ($i < $pagecount)
{
//$pdf->AddPage();
$pdf->AddPage('L',80,80,80);
}
}
if($z < $fileArcount){
$pdf->WriteHTML('<pagebreak />');
}
$z++;
}

How to generate PDF with low memory on the server?

I'm converting a table of my DB to PDF and I'm using the TCPDF.
First I have to convert my table to HTML and then I can convert to PDF, which use a lot of memory and I have a few resources on the server (256M for PHP max).
How can I pass a table that may have thousands of records to PDF with 256M memory max in PHP?
Can I create a PDF page by page and in the end concatenate all pages?
I have found a way to concatenate the pdf page from this link.
require_once("tcpdf/tcpdf.php"); //ur workspaces
require_once("fpdi/fpdi.php");
class concat_pdf extends FPDI {
var $files = array();
function setFiles($files) {
$this->files = $files;
}
function concat() {
foreach($this->files AS $file) {
$pagecount = $this->setSourceFile($file);
for ($i = 1; $i <= $pagecount; $i++) {
$tplidx = $this->ImportPage($i);
$s = $this->getTemplatesize($tplidx);
$this->AddPage(’P', array($s['w'], $s['h']));
$this->useTemplate($tplidx);
}
}
}
}
Did you try fpdf (http://www.fdpf.org) or the related mpdf (http://www.mpdf1.com) as an alternative? Maybe they use less resources so they can run on your server. They do a good job in creating HTML to PDF output.

Hex to image in PHP

Any other way to create the image from hexadecimal number?
I use a signature pad to get the signature and save it as an image and put in a PDF;
I have created the image (*.PNG) from the hex code(signiture pad generates the HExadecimal number); the image seems fine (I can open it and see it!), but for some reason this image cannot be put in the PDF by FPDF; however I can put any other images to my PDF by using FPDF; so I guess there is a problem with the image I created (HEX to Image). I created my image by the following code:
$binary = pack("H*", $MyHex);
file_put_contents("../img/Sign_Representative.png", $binary);
Do you know any other way I can create the image from HEX or any way I can handle this problem?
I appreciate your guidance!
Are you sure that signature pad provides PNG-data in HEX?
Check generated file's content if the first row contains letters "PNG" (without quotes).
Tried yours and following and all provided data correctly back:
// test 1
$binary = pack("H" . strlen($MyHex), $MyHex);
file_put_contents("../img/Sign_Representative-1.png", $binary);
// test 2
$binary = hextobin($MyHex);
file_put_contents("../img/Sign_Representative-2.png", $binary);
// #src http://www.php.net/manual/en/function.hex2bin.php#110973
function hextobin($hexstr)
{
$n = strlen($hexstr);
$sbin="";
$i=0;
while($i < $n) {
$a =substr($hexstr,$i,2);
$c = pack("H*",$a);
if ($i == 0) {
$sbin = $c;
} else {
$sbin .= $c;
}
$i += 2;
}
return $sbin;
}
btw, what kind/model signature pad you have? i.e. Honeywell TT8500?

How do I find out what the error is when Firefox says "the Image cannot be displayed because it contains errors"?

I have a PHP file that makes an image. I have PHP configured to report errors on the screen. When I run the file in the PHP file in Firefox 23, it returns the Image cannot be displayed because it contains errors.
How can I find out what particular error is at fault in the image?
Here is the code:
<?php
$tfont[] = 'cylburn-webfont.ttf';
$cryptinstall = "./cryptographp.fct.php";
include $cryptinstall;
error_reporting(E_ALL ^ E_NOTICE);
srand((double)microtime()*1000000);
if ($_GET[$_GET['sn']] == "")
unset ($_GET['sn']);
session_start();
include('getcaptcha.php');
$question = getcaptcha();
$questionLen = strlen($question);
$cryptwidth = 25 * $questionLen;
$cryptinstall2 = "./cryptographp.cfg.php";
include $cryptinstall;
$cryptwidth = 900;
$cryptheight = 200;
// CrÈation du cryptogramme temporaire
$imgtmp = imagecreatetruecolor($cryptwidth, $cryptheight);
$blank = imagecolorallocate($imgtmp, 255, 255, 255);
$black = imagecolorallocate($imgtmp, 0, 0, 0);
imagefill($imgtmp, 0, 0, $blank);
$word = '';
$x = 10;
$pair = rand(0, 1);
$charnb = rand($charnbmin, $charnbmax);
for ($i=0; $i<= $questionLen; $i++) {
$tword[$i]['font'] = $tfont[array_rand($tfont, 1)];
$tword[$i]['angle'] = (rand(1, 2) == 1) ? rand(0, $charanglemax) : rand(360-$charanglemax, 360);
$tword[$i]['element'] = str_split($question)[$i-1];
$tword[$i]['size'] = rand($charsizemin, $charsizemax);
$tword[$i]['y'] = ($charup ? ($cryptheight/2) + rand(0, ($cryptheight/5)) : ($cryptheight/1.5));
$word .= $tword[$i]['element'];
$lafont = "fonts/" . $tword[$i]['font'];
imagettftext($imgtmp, $tword[$i]['size'], $tword[$i]['angle'], $x, $tword[$i]['y'], $black, $lafont, $tword[$i]['element']);
$x += $charspace;
}
// Calculate horizontal racadrage temporary cryptogram
$xbegin = 0;
$x = 0;
while (($x<$cryptwidth)and(!$xbegin)) {
$y = 0;
while (($y<$cryptheight) and (!$xbegin)) {
if (imagecolorat($imgtmp, $x, $y) != $blank)
$xbegin = $x;
$y++;
}
$x++;
}
$xend = 0;
$x = $cryptwidth-1;
while (($x>0) and (!$xend)) {
$y = 0;
while (($y<$cryptheight)and(!$xend)) {
if (imagecolorat($imgtmp, $x, $y) != $blank)
$xend = $x;
$y++;
}
$x--;
}
$xvariation = round(($cryptwidth/2)-(($xend-$xbegin)/2));
imagedestroy ($imgtmp);
// Create the final cryptogram
// Create the background
$img = imagecreatetruecolor($cryptwidth, $cryptheight);
if ($bgimg and is_dir($bgimg)) {
$dh = opendir($bgimg);
while (false !== ($filename = readdir($dh)))
if(eregi(".[gif|jpg|png]$", $filename))
$files[] = $filename;
closedir($dh);
$bgimg = $bgimg . '/' . $files[array_rand($files, 1)];
}
if ($bgimg) {
list($getwidth, $getheight, $gettype, $getattr) = getimagesize($bgimg);
$imgread = imagecreatefrompng($bgimg); break;
imagecopyresized($img, $imgread, 0, 0, 0, 0, $cryptwidth, $cryptheight, $getwidth, $getheight);
imagedestroy ($imgread);
}
else {
$bg = imagecolorallocate($img, $bgR, $bgG, $bgB);
imagefill($img, 0, 0, $bg);
if ($bgclear)
imagecolortransparent($img, $bg);
}
function ecriture()
{
// CrÈation de l'Ècriture
global $img, $ink, $charR, $charG, $charB, $charclear, $xvariation, $charnb, $charcolorrnd, $charcolorrndlevel, $tword, $charspace;
$ink = imagecolorallocatealpha($img, $charR, $charG, $charB, $charclear);
global $question;
global $questionLen;
$x = $xvariation;
for ($i=1; $i<$questionLen; $i++) {
if ($charcolorrnd) { // Choisit des couleurs au hasard
$ok = false;
do {
$rndcolor = 0;
switch ($charcolorrndlevel) {
case 1 :
if ($rndcolor<200)
$ok = true; break; // tres sombre
default : $ok = true;
}
} while (!$ok);
$rndink = imagecolorallocatealpha($img, $rndR, $rndG, $rndB, $charclear);
}
$lafont = "fonts/" . $tword[$i]['font'];
imagettftext($img, $tword[$i]['size'], $tword[$i]['angle'], $x, $tword[$i]['y'], $charcolorrnd ? $rndink : $ink, $lafont, $tword[$i]['element']);
$x += $charspace;
}
}
// Fonction permettant de dÈterminer la couleur du bruit et la forme du pinceau
function noisecolor()
{
global $img, $noisecolorchar, $ink, $bg, $brushsize;
switch ($noisecolorchar) {
case 1 : $noisecol = $ink; break;
case 2 : $noisecol = $bg; break;
case 3 :
default : $noisecol = imagecolorallocate ($img, 0, 0, 0); break;
}
if ($brushsize and $brushsize>1 and function_exists('imagesetbrush')) {
$brush = imagecreatetruecolor($brushsize, $brushsize);
imagefill($brush, 0, 0, $noisecol);
imagesetbrush($img, $brush);
$noisecol = IMG_COLOR_BRUSHED;
}
return $noisecol;
}
//Adding noise: points, lines and circles random
function bruit()
{
global $noisepxmin, $noisepxmax, $noiselinemin, $noiselinemax, $nbcirclemin, $nbcirclemax, $img, $cryptwidth, $cryptheight;
$nbpx = rand($noisepxmin, $noisepxmax);
$nbline = rand($noiselinemin, $noiselinemax);
for ($i=1; $i<$nbpx; $i++)
imagesetpixel($img, rand(0, $cryptwidth-1), rand(0, $cryptheight-1), noisecolor());
for ($i=1; $i<=$nbline; $i++)
imageline($img, rand(0, $cryptwidth-1), rand(0, $cryptheight-1), rand(0, $cryptwidth-1), rand(0, $cryptheight-1), noisecolor());
}
if ($noiseup) {
ecriture();
bruit();
}
else {
bruit();
ecriture();
}
// Create the frame
if ($bgframe) {
$framecol = imagecolorallocate($img, ($bgR*3 + $charR)/4, ($bgG*3 + $charG)/4, ($bgB*3 + $charB)/4);
imagerectangle($img, 0, 0, $cryptwidth-1, $cryptheight-1, $framecol);
}
// Transformations supplÈmentaires: Grayscale et Brouillage
// VÈrifie si la fonction existe dans la version PHP installÈe
if ($cryptgrayscal)
imagefilter($img, IMG_FILTER_GRAYSCALE);
if ($cryptgaussianblur)
imagefilter($img, IMG_FILTER_GAUSSIAN_BLUR);
/* If I comment out these lines, then the file runs fine, but
of course it does not return an image.
header("Content-type: image/png"); // This is the only header(...) that is
// included in the file. I am requesting
// the file directly with the URL.
imagepng($img);
imagedestroy ($img);
unset ($word, $tword);
unset ($_SESSION['cryptreload']); */
?>
If I comment out the header("content-type: image/png"), it gets rid of the error, but it returns nonsense to the browser that looks like this:
(All this said, I am less interested in fixing this particular image file than in understanding how to go about debugging errors/unexpected behavior in image-creation files. I want to learn how to fix problematic image-generating files on my own.)
First make sure that no part of your code before the header() command outputs anything.
If you have any includes before your header, make sure you don't finish your PHP code with ?> because sometimes this generates a byte.
Finally try wrapping your includes inside of ob_start(); and ob_end_clean(); as this will make sure that no random bytes are cast to the output due to any other reasons (I had this happen once).
Comment out the header() so it just sends back data and not image/png.
Perhaps your PHP script messed up your images. Logical errors can't be reported, you have to find it by yourself. To turn on regular error reporting, check out this link: How do I enable error reporting in PHP?
To enable error logging
Where does PHP store the error log? (PHP 5, Apache, FastCGI, and cPanel)
In an ASP.NET Core application you may be tempted to put picture files in a folder called Images under the solution, but you need to put them in the wwwroot/images folder:
That's a trick question, isn't it?
Your script contains the line
echo('here!'); //prints here to the screen
This will prepend the ASCII string "here" to the PNG data stream, thus ruining the image.
Hint: If you download the result of your script (using e.g. wget, or simply "Save page" in Firefox), and open the file in an editor, you'll quickly see the problem.
Here's an answer from a thread at support.mozilla.org that may help others who come across this question:
I have discovered that a very common reason for this is that the image type does not match the file extension. This causes the webserver to report the wrong mime-type. For example, if you take a photoshop image, rename it to a .jpg file, and put it on a webserver, it will not load in Firefox.
If you are working on troubleshooting this issue, try downloading the file and verifying that the file type matches the jpg. I fixed this for a client today who took a .psd file, renamed it to .jpg, uploaded it to a webserver, and wondered why it wouldn't load in Firefox.
Read your PHP error log and you will find out the exact error. Most probably PHP is throwing a warning. That's the reason you are seeing this error in your browser.
I hope this might save a hour for someone troubleshooting .NET Core applications on Linux:
In my case it wasn't actually the issue with the image. The problem was a server-side uppercase directory/file name. In the Windows file system filename, case doesn't matter while the Linux file system is case-sensitive.
For my case, it was Visual Studio's fault for the error. I started to add the image to the code via the img tag, and Visual Studio guided me through it with IntelliSense I guess. The funny thing is, it added the wrong path. This is what it added in for me:
<img src="~/images/home-couple.jpg" />
Where it should have been:
<img src="images/home-couple.jpg" />
The location of the images folder is right under wwwroot. This is an ASP.NET Core web application.
Before the header line insert this function
ob_clean();
like in the example:
$image = file_get_contents($imageFilePath);
ob_clean(); // <-DON'T FORGET THIS LINE
header('Content-type: image/jpeg'); //jpeg, png, bmp...
header("Content-Disposition: filename=".basename($imageFilePath));
echo $image;
ob_clean() is used to clean (erase) the output buffer. So, if there is something else echoed beofre the header, it will be erased;

Categories