Welcome to a tutorial on how to add a watermark to an image in PHP. So you have an eCommerce website or gallery that accepts image uploads, but there is just one problem. Some thieves are stealing the images, and a little bit of protection will do good.
We can use the GD extension in PHP to add a watermark to images:
- Open the original image –
$img = imagecreatefromjpeg("IMAGE.JPG");
- Set the text color –
$red = imagecolorallocatealpha($img, 255, 0, 0);
- Add the text to the image –
imagettftext($img, 18, 0, 0, 24, $red, "PATH\FONT.TTF", "COPYRIGHT");
- Save the watermarked image –
imagejpeg($img, "WATERMARKED.JPG", 60);
That covers the quick basics, but how do we apply another image as the watermark? Read one for more examples!
ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
QUICK SLIDES
TABLE OF CONTENTS
DOWNLOAD & NOTES
First, here is the download link to the example source code as promised.
QUICK NOTES
- Make sure that the GD extension is enabled in
php.ini
–extension=gd
(orgd2
prior to PHP8). - For
l-text.php
and3-text-pos.php
, make sure$font = "PATH/TO/FONT"
is correct and PHP has read access to the font file.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
ADDING WATERMARK WITH PHP
All right, let us now get into the examples of applying a watermark to an image in PHP now.
EXAMPLE 1) ADD TEXT WATERMARK TO IMAGE
<?php
// (X) QUICK FUNCTION REFERENCE
// imagecolorallocatealpha (IMAGE, RED, GREEN, BLUE, OPACITY)
// imagettftext(IMAGE, SIZE, ANGLE, X, Y, COLOR, FONT, TEXT)
// imagejpeg (IMAGE, FILE, QUALITY)
// (A) SETTINGS
$source = "doge.jpg"; // SOURCE IMAGE
$target = "watermarked.jpg"; // WATERMARKED IMAGE
$quality = 60; // WATERMARKED IMAGE QUALITY (0 to 100)
$copytxt = "Copyright"; // COPYRIGHT TEXT
$font = "C:\Windows\Fonts\arial.ttf"; // MAKE SURE PATH IS CORRECT!
$fontsize = 18; // FONT SIZE
$posX = 0; // PLACE WATERMARK AT LEFT OF IMAGE
$posY = 24; // PLACE WATERMARK AT TOP OF IMAGE
// (B) CREATE IMAGE OBJECT
$img = imagecreatefromjpeg($source);
// (C) WRITE TEXT TO IMAGE (TOP LEFT CORNER)
$fontcolor = imagecolorallocatealpha($img, 255, 0, 0, 75);
imagettftext($img, $fontsize, 0, $posX, $posY, $fontcolor, $font, $copytxt);
// (D) SAVE TO FILE
imagejpeg($img, $target, $quality);
echo "Saved to $target";
Look no further, this is pretty much the same steps as the above introduction snippet.
- A couple of settings – The source image file, watermark text, font to use, etc…
- Read the original image.
- Watermark the image.
- Save the watermarked image to a file.
EXAMPLE 2) ADD AN IMAGE WATERMARK
<?php
// (X) QUICK FUNCTION REFERENCE
/* imagecopy (
* DESTINATION, SOURCE,
* DESTINATION-X, DESTINATION-Y,
* SOURCE-X, SOURCE-Y,
* SOURCE-WITDTH, SOURCE-HEIGHT
* )
*/
// (A) SETTINGS
$sourceS = "doge.jpg"; // SOURCE IMAGE
$sourceW = "potato.png"; // WATERMARK IMAGE
$target = "watermarked.jpg"; // WATERMARKED IMAGE
$quality = 60; // WATERMARKED IMAGE QUALITY (0 to 100)
$posX = 0; // PLACE WATERMARK AT LEFT CORNER
$posY = 0; // PLACE WATERMARK AT TOP CORNER
// (B) CREATE IMAGE OBJECTS
$imgS = imagecreatefromjpeg($sourceS);
$imgW = imagecreatefrompng($sourceW);
// (C) APPLY WATERMARK
imagecopy(
$imgS, $imgW, // COPY WATERMARK ONTO SOURCE IMAGE
$posX, $posY, // PLACE WATERMARK AT TOP LEFT CORNER
0, 0, imagesx($imgW), imagesY($imgW) // COPY FULL WATERMARK IMAGE WITHOUT CLIPPING
);
// (D) OUTPUT
imagejpeg($imgS, $target, $quality);
echo "Saved to $target";
This version will apply an image watermark instead, it is a lot more straightforward – We are just “copying” the watermark onto the uploaded image using imagecopy()
. For the uninitiated, please use PNG WEBP GIF
for the watermark image. JPEG does not support alpha channels (transparency).
EXAMPLE 3) POSITION (CENTER) THE TEXT WATERMARK
<?php
// (A) SETTINGS
$source = "doge.jpg"; // SOURCE IMAGE
$target = "watermarked.jpg"; // WATERMARKED IMAGE
$quality = 60; // WATERMARKED IMAGE QUALITY (0 to 100)
$copytxt = "Copyright"; // COPYRIGHT TEXT
$font = "C:\Windows\Fonts\arial.ttf"; // MAKE SURE PATH IS CORRECT!
$fontsize = 18; // FONT SIZE
// (B) CREATE IMAGE OBJECT
$img = imagecreatefromjpeg($source);
// (C) POSITION CALCULATIONS
// (C1) SOURCE IMAGE DIMENSIONS
$widthS = imagesx($img);
$heightS = imagesy($img);
// (C2) TEXT BOX DIMENSIONS
$sizeT = imagettfbbox($fontsize, 0, $font, $copytxt);
$widthT = max([$sizeT[2], $sizeT[4]]) - min([$sizeT[0], $sizeT[6]]);
$heightT = max([$sizeT[5], $sizeT[7]]) - min([$sizeT[1], $sizeT[3]]);
// (C3) CENTER POSITION
$posX = CEIL(($widthS - $widthT) / 2);
$posY = CEIL(($heightS - $heightT) / 2);
if ($posX < 0 || $posY < 0) { exit("Text is too long"); } // OPTIONAL ERROR HANDLE
// (D) WRITE TEXT TO IMAGE
$fontcolor = imagecolorallocatealpha($img, 255, 0, 0, 30);
imagettftext($img, $fontsize, 0, $posX, $posY, $fontcolor, $font, $copytxt);
// (E) SAVE TO FILE
imagejpeg($img, $target, $quality);
echo "Saved to $target";
This is the same as above, but with additional calculations to center the text watermark… How positioning works is unfortunately very Mathematical. Not going to explain line-by-line, but in a summary:
- Use
imagesx()
andimagesy()
to get the dimensions of the source image. - Use
$sizeT = imagettfbbox()
to get an array of 8 numbers, which are the X-Y coordinates of the text box (illustration below).
- To calculate the dimensions of the text box:
- For the width, take the rightmost point
max([$sizeT[2], $sizeT[4]])
, minus the leftmost pointmin([$sizeT[0], $sizeT[6]])
. - For the height, take the topmost point
max([$sizeT[5], $sizeT[7]])
, minus the bottommost pointmin([$sizeT[1], $sizeT[3]])
.
- For the width, take the rightmost point
- With that, we can finally do calculations to center the text.
- Horizontal center =
(Image Width - Text Width) / 2
. - Vertical center =
(Image Height - Text Height) / 2
.
- Horizontal center =
EXAMPLE 4) POSITION (CENTER) THE IMAGE WATERMARK
<?php
// (A) SETTINGS
$sourceS = "doge.jpg"; // SOURCE IMAGE
$sourceW = "potato.png"; // WATERMARK IMAGE
$target = "watermarked.jpg"; // WATERMARKED IMAGE
$quality = 60; // WATERMARKED IMAGE QUALITY (0 to 100)
// (B) CREATE IMAGE OBJECTS
$imgS = imagecreatefromjpeg($sourceS);
$imgW = imagecreatefrompng($sourceW);
// (C) POSITION CALCULATIONS
// (C1) SOURCE & WATERMARK DIMENSIONS
$widthS = imagesx($imgS);
$heightS = imagesY($imgS);
$widthW = imagesx($imgW);
$heightW = imagesY($imgW);
// (C2) CENTER POSITION
$posX = CEIL(($widthS - $widthW) / 2);
$posY = CEIL(($heightS - $heightW) / 2);
if ($posX < 0 || $posY < 0) { exit("Watermark image is too large"); } // OPTIONAL ERROR HANDLE
// (D) APPLY WATERMARK
imagecopy(
$imgS, $imgW, // COPY WATERMARK ONTO SOURCE IMAGE
$posX, $posY, // PLACE WATERMARK AT TOP LEFT CORNER
0, 0, $widthW, $heightW // COPY FULL WATERMARK IMAGE WITHOUT CLIPPING
);
// (E) OUTPUT
imagejpeg($imgS, $target, $quality);
echo "Saved to $target";
Finally, centering an image watermark is also… Mathematical. But it is thankfully a lot simpler:
- Horizontal Center =
(Source Width - Watermark Width) / 2
- Vertical Center =
(Source Height - Watermark Height) / 2
USEFUL BITS & LINKS
That’s all for this guide, and here is a small section on some extras and links that may be useful to you.
HOW TO SET THE OPACITY OF THE IMAGE WATERMARK?
Unfortunately, the GD library doesn’t seem to have a straightforward method to set image opacity. So, use your own image editor to set the watermark opacity.
SUMMARY – USEFUL GD FUNCTIONS
Function | Description | Reference Link |
imagecreatefromjpeg() |
Create a GD image object from a JPG file. | Click Here |
imagecolorallocatealpha() |
Allocates a color with alpha (transparency). | Click Here |
imagettftext() |
Writes text to the image using TTF. | Click Here |
imagesx() |
Get the width of an image. | Click Here |
imagesy() |
Get the height of an image. | Click Here |
imagettfbbox() |
Get the dimensions of a block of text. | Click Here |
imagecopy() |
Copy an image onto another image. | Click Here |
imagejpeg() |
Save to a JPEG image file. | Click Here |
LINKS & REFERENCES
- Very Simple File Upload – Code Boxx
- How to Add Text to Images In PHP (Plus Center It) – Code Boxx
- Adding watermarks to images using alpha channels – PHP
TUTORIAL VIDEO
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!