February 27, 2010

Creating image watermarks in OpenCart

Filed under: Tips — Tags: , — Webopius @ 7:42 pm

We’ve been using the fantastic OpenCart e-commerce system (see link to the right) for some time now on a number of sites.

Related Links…
OpenCart Open Source shopping

OpenCart has almost every feature that you need to build an e-commerce solution quickly. More importantly, it can be extended easily and has a strong online community. We’ve recently made a simple enhancement to one of the stores we developed (the Orchid Store) to overlay product images with a watermark like this:


It’s a really simple change and I thought it would be useful to others if I posted how to do it. Please note, this solution is a ‘quick implementation’ and can be enhanced further.

Step 1. Create your watermark overlay image

The first step is to create a small image that will become the watermark overlaying your product images. I would recommend using a transparent PNG format. In the example above, the background of the watermark is transparent and the text is set to 50% opacity.

Save this image as ‘watermark.png’ in your site’s /images/userfiles directory.

Step 2. Create some new OpenCart image functions

The next step is to create a couple of new watermark functions within the OpenCart system area. Open the /system/library/image.php file. You will see that there is already a watermark() function available.

In this example, we are going to create a new watermark function as it makes handling any upgrades of OpenCart slightly easier and you are adding to rather than changing any existing functionality. You may prefer to edit the existing watermark() function directly.

The new function looks like this:

public function addwatermark($position = 'bottomright') {
        $watermark = imagecreatefrompng(DIR_IMAGE . 'userfiles/watermark.png');
        $watermark_width = imagesx($watermark);
        $watermark_height = imagesy($watermark);
        switch($position) {
            case 'topleft':
                $watermark_pos_x = 0;
                $watermark_pos_y = 0;
            case 'topright':
                $watermark_pos_x = $this->info['width'] - $watermark_width;
                $watermark_pos_y = 0;
            case 'bottomleft':
                $watermark_pos_x = 0;
                $watermark_pos_y = $this->info['height'] - $watermark_height;
            case 'bottomright':
                $watermark_pos_x = $this->info['width'] - $watermark_width;
                $watermark_pos_y = $this->info['height'] - $watermark_height;
           case 'middle':
                $watermark_pos_x = ($this->info['width'] - $watermark_width)/2;
                $watermark_pos_y = ($this->info['height'] - $watermark_height)/2;
        imagecopy($this->image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0, $watermark_width, $watermark_height);

What the function above is doing is creating an image object from your watermark (use imagecreatefromgif() if you have chosen a gif format) and then placing this watermark over the image (supplied in $this) in a position you specify (topleft, topright, bottomleft, bottomright or middle).

Now, edit /system/helper/image.php and add the following code as an additional function:

function image_watermark($filename) {
	if ( (!file_exists(DIR_IMAGE . $filename)) && (!file_exists(DIR_IMAGE . 'cache/' . $filename)) ) {
	if (file_exists(DIR_IMAGE . 'cache/' . $filename)) {
		$old_image = DIR_IMAGE . 'cache/' . $filename;
	} else {
		$old_image = DIR_IMAGE . $filename;
	$new_image = 'cache/' . substr($filename, 0, strrpos($filename, '.')) . '-w.jpg';
	if (!file_exists(DIR_IMAGE . $new_image) || (filemtime($old_image) > filemtime(DIR_IMAGE . $new_image))) {
		$image = new Image($old_image);
		$image->save(DIR_IMAGE . $new_image);

	if (isset($_SERVER['HTTPS']) && (($_SERVER['HTTPS'] == 'on') || ($_SERVER['HTTPS'] == '1'))) {
		return HTTPS_IMAGE . $new_image;
	} else {
		return HTTP_IMAGE . $new_image;

What the above code is doing is being given a product image filename ($filename). It then checks in both the standard image directory and the cache directory for that product image. This is slightly non standard from the usual OpenCart which only looks in the main image directory. We added the second cache check because we will call this watermark function after the product image has been re-sized and placed in the cache directory.

What the code then does is create a new ‘watermarked’ filename for the image by appending a ‘-w.jpg’ to the existing filename. It then checks the cache to see if a watermark has already been created. If not, it calls the addwatermark() function we just created. The resulting watermarked image filename is then returned.

Step 3. Modify your OpenCart product template to show the watermark

The watermark function can of course be used in any templates and image fields you choose. In this example, we are using the ‘popup’ product image field. Locate the product.php file in your sites /catalog/controller/product directory. Look for a line similar to this in the code:

$this->data['popup']  = image_resize($image, $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height'));	

…and change it to this:

$productimage = image_resize($image, $this->config->get('config_image_popup_width'),$this->config->get('config_image_popup_height'));
$wmimage = image_watermark(basename($productimage));
$this->data['popup'] = $wmimage;

This adds an additional step to the process. After resizing the image, the $productimage file will be placed in the cache. Image_watermark() is then called to overlay the product image with your watermark.

Hopefully, if you’ve followed these steps your site will now be showing product images with watermarks added. As I mentioned at the start, this solution can be extended and improved further and it would be good to hear feedback from others.

The OpenCart image library also contains a number of other hidden features including rotation and cropping. We have also extended the OpenCart image helpers further with dynamic image scaling. If anyone is interested in this, please get in touch.

  • Tags