Adding Watermark to an Image in PHP using GD Library Tutorial

Introduction

In this tutorial, I will teach you how to Add a Watermark to an Image in PHP. Here, you can learn how to manage or edit images using the PHP GD Library. The tutorial aims to provide students and those new to PHP Language a reference for using GD Library to learn. I will be providing some snippets on how to achieve our goal for this tutorial. Also, I will be giving a sample source code that adds watermarks to uploaded images.

What is GD Library?

An open-source code package called GD is used to create images dynamically. PNG, JPEG, and GIF images can be created using GD, which is also frequently used to instantly generate charts, graphics, and thumbnails. Although not limited to the web, developing websites is one of GD's most popular applications.

How to enable GD Library?

To enable the GD library, you will need to uncomment or add the GD Extension to your php.ini file as extension. Follow the instruction below.

  1. Locate your php.ini file.
  2. Open the file with your preferred text editor.
  3. Find the line with the GD extension by searing the extension=gd keyword.
  4. Remove the semi-colon (;) located before the extension word.

Enabling GD Library in php.ini

How do you Add a Watermark to an Image in PHP?

Here's the snippet that can add a watermark to an Image. Using the imagecreatejpeg/imagecreatepng and imagecopy. This way is one of many ways to achieve our goal for this tutorial. See the snippet below.

  1. <?php
  2. // uploaded image
  3. $uploaded_img = "sample.png";
  4. // watermark image
  5. $watermark = "watermark.png";
  6.  
  7. //creating GD images
  8. $img = imagecreatepng($uploaded_img);
  9. $water_img = imagecreatepng($watermark);
  10.  
  11. // Getting the size of the uploaded image
  12. list($width, $height) = getimagesize($uploaded_img);
  13.  
  14.  
  15. // Getting the size of the watermark image
  16. list($w_width, $w_height) = getimagesize($watermark);
  17.  
  18. // Add Watermark to uploaded image
  19. imagecopy($img, $water_img, $width - $w_width, $height - $w_height, 0, 0, $width, $height);
  20.  
  21. // saving the image with watermark
  22. imagepng($img, "image_with_watermark.png");
  23.  
  24. //destroy the GD image

The snippet above will combine the 2 images which are your uploaded image and the watermark image. The watermark can be seen on the bottom-right of the uploaded image. The snippets only demonstrate how to add a watermark to an image which means if you copy this code you must consider creating some logic to handle errors such as the uploaded image size being smaller than the watermark or where you want to display the watermark.

Example

Here are the snippets of an example application that demonstrates how to add a watermark to an Image. The application allows users to upload an image and automatically create a copy that contains a watermark. The watermark is placed at the center of the image. The watermark image automatically scales down if it has a bigger size than the uploaded image.

index.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.     <title>Add Watermark to an Image in PHP</title>
  8.  
  9.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  10.     <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
  11.     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
  12.     <style>
  13.         html, body{
  14.             min-height:100%;
  15.             width:100%;
  16.         }
  17.         .img-holder {
  18.             text-align: center;
  19.             height: 20vw;
  20.             border: 1px solid;
  21.             width: 100%;
  22.             display: flex;
  23.             justify-content: center;
  24.             align-items: center;
  25.             background: black;
  26.         }
  27.         .img-holder > img{
  28.             max-height:calc(100%);
  29.             max-width:calc(100%);
  30.             object-fit:scale-down;
  31.             object-position:center center;
  32.         }
  33.     </style>
  34. </head>
  35. <body>
  36.     <nav class="navbar navbar-expand-lg navbar-dark bg-primary bg-gradient">
  37.         <div class="container">
  38.             <a class="navbar-brand" href="./">Adding Watermark to an Image in PHP</a>
  39.             <div>
  40.                 <a href="https://sourcecodester.com" class="text-light fw-bolder h6 text-decoration-none" target="_blank">SourceCodester</a>
  41.             </div>
  42.         </div>
  43.     </nav>
  44.     <div class="container-fluid px-5 my-3">
  45.         <div class="border px-3 py-2 rounded">
  46.                 <form action="upload.php" method="POST" enctype="multipart/form-data">
  47.                     <div class="col-lg-6 col-md-8 col-sm-12 mx-auto">
  48.                         <div class="mb-3">
  49.                             <label for="upload" class="form-label">Upload File</label>
  50.                             <input class="form-control" type="file" name="upload" accept="image/jpeg, image/png" id="upload">
  51.                         </div>
  52.                         <div class="mb-3 d-grid">
  53.                             <button class="btn btn-primary btn-block rounded-pill">Upload and add Watermark</button>
  54.                         </div>
  55.                     </div>
  56.                 </form>
  57.         </div>
  58.         <div class="clearfix my-3"></div>
  59.         <div class="row">
  60.             <div class="col-lg-6">
  61.                 <div class="card round-0">
  62.                     <div class="card-body">
  63.                         <div class="img-holder">
  64.                             <?php if(is_file("upload/original.png")): ?>
  65.                             <img src="upload/original.png?v=<?= time() ?>" alt="">
  66.                             <?php endif; ?>
  67.                         </div>
  68.                     </div>
  69.                 </div>
  70.             </div>
  71.             <div class="col-lg-6">
  72.                 <div class="card round-0">
  73.                     <div class="card-body">
  74.                         <div class="img-holder">
  75.                             <?php if(is_file("upload/copy_w_watermark.png")): ?>
  76.                             <img src="upload/copy_w_watermark.png?v=<?= time() ?>" alt="">
  77.                             <?php endif; ?>
  78.                         </div>
  79.                     </div>
  80.                 </div>
  81.             </div>
  82.         </div>
  83.         <div class="clearfix my-3"></div>
  84.         <div class="col-lg-4 mx-auto d-grid">
  85.             <a class="btn btn-primary rounded-pill" href="upload/copy_w_watermark.png?v=<?= time() ?>" download="image_w_watermark.png">Download the Image with Watermark</a>
  86.         </div>
  87.     </div>
  88. </body>
  89. </html>

upload.php

  1. <?php
  2. if(!isset($_FILES['upload']) || (isset($_FILES['upload']) && empty($_FILES['upload']['tmp_name']))){
  3.     echo "<script>alert(`Please Upload Image First.`); location.replace('./');</script>";
  4.     exit;
  5. }
  6.  
  7.  
  8. //File Extension
  9. $ext =  pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION);
  10.  
  11. //File Type
  12. $type = mime_content_type($_FILES['upload']['tmp_name']);
  13.  
  14. // Allowed File Type
  15. $allowed_type = ["image/jpeg", "image/png"];
  16. if(!in_array($type, $allowed_type)){
  17.     echo "<script>alert(`Upload File type is invalid.`); location.replace('./');</script>";
  18.     exit;
  19. }
  20. // upload directory
  21. $dir = "upload/";
  22.  
  23. if(!is_dir($dir))
  24. mkdir($dir);
  25.  
  26. // orginal file name
  27. $original = "original.png";
  28. // with watermark file name
  29. $ww_copy = "copy_w_watermark.png";
  30. if(is_file($dir.$original)){
  31.     unlink($dir.$original);
  32. }
  33. if(is_file($dir.$ww_copy)){
  34.     unlink($dir.$ww_copy);
  35. }
  36.  
  37. // watermark image
  38. $watermark = "watermark.png";
  39. // $watermark = "upload/resized_wm.png";
  40. $wm_img = imagecreatefrompng($watermark);
  41.  
  42.  
  43. // watermark image size
  44. list($width, $height) = getimagesize($watermark);
  45. $w_width = $width;
  46. $w_height = $height;
  47.  
  48. // Creating an GD Image
  49.  
  50. if($type == 'image/png')
  51.     $img = imagecreatefrompng($_FILES['upload']['tmp_name']);
  52. else{
  53.     $img = imagecreatefromjpeg($_FILES['upload']['tmp_name']);
  54. }
  55. // getting the Image size
  56.  
  57. list($width, $height) = getimagesize($_FILES['upload']['tmp_name']);
  58. imagepng($img, $dir.$original);
  59.  
  60. // rescale the watermark size if it larger than the uploaded image
  61. if($w_width > $width){
  62.     $perc = ($w_width - ($width * .6)) / ($width * .6);
  63.     $w_width = ($width * .6);
  64.     $w_height = $w_height - ($w_height * $perc);
  65.     $new_wm_img = imagescale($wm_img, $w_width, $w_height);
  66.     imagealphablending($new_wm_img, true);
  67.     imagesavealpha($new_wm_img, true);
  68. }
  69.  
  70. // if($w_height > $height){
  71. //     $perc = ($w_height - ($height * .6)) / ($height * .6);
  72. //     $w_height = ($height * .6);
  73. //     $w_width = $w_width - ($w_width * $perc);
  74. //     $new_wm_img =imagescale($wm_img, $w_width, $w_height);
  75. //     imagealphablending($new_wm_img, false);
  76. //     imagesavealpha($new_wm_img, true);
  77. // }
  78. if(isset($new_wm_img)){
  79.     imagepng($new_wm_img, "upload/resized_wm.png");
  80.     imagedestroy(($new_wm_img));
  81.     imagedestroy(($wm_img));
  82.     $wm_img = imagecreatefrompng("upload/resized_wm.png");
  83.     list($w_width, $w_height) = getimagesize("upload/resized_wm.png");
  84. }
  85.  
  86.  
  87.  
  88. // Combine Image
  89. // imagecopy($img, $wm_img,
  90. //         $width,
  91. //         $height,
  92. //         (($width > $w_width) ? ($width - $w_width) / 2 : 0),
  93. //         (($height > $w_height) ? ($height - $w_height) / 2 : 0),
  94. //         (($width > $w_width) ? $w_width : $width),
  95. //         (($height > $w_height) ? $w_height : $height)
  96. // );
  97. imagecopy($img, $wm_img,
  98.         (($width > $w_width) ? ($width - $w_width) / 2 : 0),
  99.         (($height > $w_height) ? ($height - $w_height) / 2 : 0),
  100.         0,
  101.         0,
  102.         (($width > $w_width) ? $w_width : $width),
  103.         (($height > $w_height) ? $w_height : $height)
  104. );
  105.  
  106. // imagecopy($img, $wm_img,
  107. //         $width-10,
  108. //         $height-10,
  109. //         0,
  110. //         0,
  111. //         (($width > $w_width) ? $w_width : $width),
  112. //         (($height > $w_height) ? $w_height : $height)
  113. // );
  114.  
  115. imagepng($img, $dir.$ww_copy);
  116. imagedestroy($wm_img);
  117. if(is_file("upload/resized_wm.png"))
  118. unlink("upload/resized_wm.png");
  119. echo "<script>alert(`File has been uploaded successfully.`); location.replace('./');</script>";
  120. ?>

Snapshot

Here's the snapshot of the result of the above snippets.

Generate Image with watermark in PHP

DEMO VIDEO

The sample application creates an upload directory to the source code folder root path to store the uploaded and with a watermarked copy of the image. Users can also download the copy with the watermark. The complete source code of this application is provided on this site. You can download the source code zip file for free by clicking the Download Button below this article.

That's the end of this tutorial. I hope this tutorial helps you with what you are looking for and adds up to your knowledge of using the PHP GD library. Feel free to leave a comment with any queries or questions you have regarding this tutorial.

Explore more on this website for Tutorials and Free Source Codes.

Happy Coding :)

Add new comment