Add Watermark to Image in PHP

In this post we are going to add watermark to an image in php.You may have visited sites where you upload any image and it adds website's watermark to image automatically, We will learn how can we achieve that in this post.

Add Watermark to Image in PHP

Ok so files we are going to need are:

  1. index.php: The index page containing form to upload an image for watermark to be added on.
  2. process-watermark.php: The file to process form submission and add watermark to uploaded image.
  3. style.css: The css/styles for index.php

index.php

<!DOCTYPE html>
<html>
<head>
<title>Add Watermark to Image in PHP - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div class="container">
<div class="my-4">
<form class="mb-4" action="process-watermark.php" method="POST" enctype="multipart/form-data">
<div class="row">
<div class="col-12">
<div class="config-wrapper">
<label>
<input type="radio" name="position" value="repeat_all" checked="checked">
Repeat All
</label>
<label>
<input type="radio" name="position" value="top_left">
Top Left
</label>
<label>
<input type="radio" name="position" value="top_right">
Top Right
</label>
<label>
<input type="radio" name="position" value="bottom_left">
Bottom Left
</label>
<label>
<input type="radio" name="position" value="bottom_right">
Bottom Right
</label>
<label>
<input type="radio" name="position" value="center">
Center
</label>
</div>
</div>
</div>

<div class="row">
<div class="col-6">
<input type="file" class="file-input" name="image_file" />
</div>
<div class="col-6 text-right">
<button type="submit" class="btn btn-blue">
<i class="fa fa-upload"></i>
Upload
</button>
</div>
</div>
</form>
<?php if(file_exists('images/watermark-image.png')){?>
<div class="row">
<div class="col-12">
<img src="images/watermark-image.png?v=<?=time()?>" class="img-responsive"/>
</div>
</div>
<?php }?>
</div>
</div>
</body>
</html>

process-watermark.php

  1. Checks if file was uploaded without any error.
  2. Checks if file type is an image and is below specific size.
  3. Gets upload image and stamp image width & height.
  4. Sets $spacing and $spacing_double variables. $spacing_double is used for adding equal spacing on all sides.
  5. Checks what type of watermark placements was selected and adds the watermark to uploaded image accordingly.
  6. Finally saves the image as PNG and redirects back
     
<?php
// If image was uploaded without any errors, Proceed to watermarking
if($_FILES && $_FILES['image_file']['error'] === 0){
$file = $_FILES['image_file'];
$file_type = substr($_FILES['image_file']['type'], 0, 5);
$file_size = number_format($_FILES['image_file']['size'] / 1024, 2);

if($file_type == 'image' && $file_size < 2048){
$destination_image = imagecreatefromstring(file_get_contents($file['tmp_name']));
$stamp = imagecreatefrompng('images/watermark.png');

$spacing = 15;
$spacing_double = $spacing * 2;

list($width,$height) = getimagesize($file['tmp_name']);
list($stamp_width,$stamp_height) = getimagesize('images/watermark.png');

switch(filter_input(INPUT_POST, 'position', FILTER_SANITIZE_STRING)){
// Repeat watermark over whole image
case 'repeat_all':
// calculate how many rows & columns watermark will repeat
$rows = floor($height / ($stamp_height + $spacing_double));
$cols = floor($width / ($stamp_width + $spacing_double));

// Initial offset (point to start) of watermark
$offsetX = intval(($width - ($cols * ($stamp_width + $spacing_double))) / 2 + $spacing);
$offsetY = intval(($height - ($rows * ($stamp_height + $spacing_double))) / 2 + $spacing);

// Loop through all rows & columns and place watermark
for($rc = 0 ; $rc < $rows ; $rc++){
for($cc = 0; $cc < $cols; $cc++){
imagecopy($destination_image, $stamp, $cc * ($stamp_width + $spacing_double) + $offsetX, $rc * ($stamp_height + $spacing_double) + $offsetY, 0, 0, $stamp_width, $stamp_height);
}
}
break;
// Place watermark to top left of uploaded image
case 'top_left':
$offsetX = $spacing;
$offsetY = $spacing;
imagecopy($destination_image, $stamp, $offsetX, $offsetY, 0, 0, $stamp_width, $stamp_height);
break;
// Place watermark to top right of uploaded image
case 'top_right':
$offsetX = $width - ($stamp_width + $spacing);
$offsetY = $spacing;
imagecopy($destination_image, $stamp, $offsetX, $offsetY, 0, 0, $stamp_width, $stamp_height);
break;
// Place watermark to bottom left of uploaded image
case 'bottom_left':
$offsetX = $spacing;
$offsetY = $height - ($stamp_height + $spacing);
imagecopy($destination_image, $stamp, $offsetX, $offsetY, 0, 0, $stamp_width, $stamp_height);
break;
// Place watermark to bottom right of uploaded image
case 'bottom_right':
$offsetX = $width - ($stamp_width + $spacing);
$offsetY = $height - ($stamp_height + $spacing);
imagecopy($destination_image, $stamp, $offsetX, $offsetY, 0, 0, $stamp_width, $stamp_height);
break;
// Place watermark to center of uploaded image, Also the default case
case 'center':
default:
$offsetX = ($width - ($stamp_width + $spacing)) / 2;
$offsetY = ($height - ($stamp_height + $spacing)) / 2;
imagecopy($destination_image, $stamp, $offsetX, $offsetY, 0, 0, $stamp_width, $stamp_height);
break;
}

// Save image after adding watermark
imagepng($destination_image, 'images/watermark-image.png', 9);
}
}

// Redirect back
header('Location: ' . $_SERVER['HTTP_REFERER']);

style.css

*{
box-sizing: border-box;
}
html,body{
margin: 0;
padding: 0;
}
body{
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
line-height: 1.5;
}
.container{
width: 100%;
max-width: 1140px;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
.my-4{
margin-top: 1rem;
margin-bottom: 1rem;
}
.mb-4{
margin-bottom: 1rem;
}
.text-right{
text-align: right;
}
.row{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}
.col-6,
.col-12{
width: 100%;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
.col-6{
-webkit-box-flex: 0;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
}
.col-12{
-webkit-box-flex: 0;
-ms-flex: 0 0 100%;
flex: 0 0 100%;
max-width: 100%;
}
.img-responsive{
max-width: 100%;
height: auto;
}
.btn{
display: inline-block;
padding: 5px 10px;
cursor: pointer;
font: inherit;
}
.btn-blue{
background-color: #006699;
border: 1px solid #2b7cab;
color: #ffffff;
}
.config-wrapper{
background: #fff;
padding: 0.75rem;
margin-bottom: 1rem;
}
.config-wrapper label{
display: inline-block;
margin-right: 10px;
}