# Watermark Image

**URL:** https://meta.discourse.org/t/watermark-image/347138
**Category:** Theme component
**Created:** [January 14, 2025, 9:13pm UTC](https://meta.discourse.org/t/watermark-image/347138 "2025-01-14T21:13:27Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 14, 2025, 9:13pm UTC](https://meta.discourse.org/t/watermark-image/347138/1 "2025-01-14T21:13:27Z")

</div>

| | | |
| --- | --- | --- |
| ℹ | **Summary** | Automatically adds watermarks to user-uploaded images |
| 🛠 | **Repository** | [GitHub - Arkshine/discourse-watermark-image · GitHub](https://github.com/Arkshine/discourse-watermark-image/) |
| ❓ | **Install Guide** | [How to install a theme or theme component](https://meta.discourse.org/t/how-do-i-install-a-theme-or-theme-component/63682) |
| 📖 | **New to Discourse Themes?** | [Beginner’s guide to using Discourse Themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) |

Install this theme component

## Description

This theme component automatically adds watermarks to user-uploaded images. You can use either an image or a QR code as your watermark, with extensive customization options for position, appearance, and distribution patterns.

The component offers granular control through category and user group settings, allowing you to tailor the watermarking behavior to your community’s needs.

_Please review the [Important Notes](#p-1687231-important-notes-8) section before implementation._

 ![Comparison before and after watermark is applied](https://global.discourse-cdn.com/meta/original/4X/0/4/e/04e7acd723a640244e55a7d057b76458338f3fc4.jpeg)

## Features

- High-performance processing using [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) and [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
- Comprehensive image format support (PNG, JPEG, BMP, ICO, TIFF, WEBP)
- Dynamic QR code watermark generation
- Flexible sizing options (relative or absolute)
- Versatile positioning system
- Advanced appearance customization (opacity, rotation, scale, margin, etc.)
- Multiple blending modes
- Pattern distribution options (single, grid, diagonal, random)
- Category and user group-specific settings
- Live preview in settings panel

 ![Example watermark 1](https://global.discourse-cdn.com/meta/original/4X/8/4/4/8441f0c9e39cedfab9a807607d48ad1f875ce0be.jpeg) ![Example watermark 2](https://global.discourse-cdn.com/meta/original/4X/4/f/1/4f1df1f69f22b4b60253b71824156c400ec275bd.jpeg) ![Example watermark 3](https://global.discourse-cdn.com/meta/original/4X/c/c/c/ccc31e6bf115a33e2ded70c9251fcfb3dfb91bc9.jpeg) ![Example watermark 4](https://global.discourse-cdn.com/meta/original/4X/e/0/6/e06222724ca40308e26eb1c5d64e7b0e26a49e88.jpeg)

## Settings

| Setting | Description |
| --- | --- |
| `image` | The image to use as watermark.   
Supported formats: PNG, JPEG, BMP, ICO, TIFF, WEBP.  
Default: `""` |
| `size_mode` | How the watermark size is calculated:  
- `relative`: Size is relative to the target’s image width.  
- `absolute`: Applied at its original size.  
Default: `"relative"` |
| `relative_width` | The width of the watermark relative to the target image width (in %).  
Only applies when the watermark size mode is set to `relative`.  
 Range: 1-100  
Default: `10` |
| `absolute_scale` | Scale factor for original watermark size (only used in absolute mode). Min: 0.01  
Default: `1` |
| `max_size` | Maximum size as percentage of image dimensions. Range: 1-100  
Default: `50` |
| `position` | Position of the watermark: `top-left`, `top-center`, `top-right`, `center-left`, `center`, `center-right`, `bottom-left`, `bottom-center`, `bottom-right`  
Default: `"bottom-right"` |
| `margin_x` | Horizontal margin from the edge (in % of the target image)  
Default: `0` |
| `margin_y` | Vertical margin from the edge (in % of the target image)  
Default: `0` |
| `opacity` | Watermark opacity. Range: 1-100  
Default: `100` |
| `rotate` | Rotation angle.   
Range: -360 to 360 degrees  
Default: `0` |
| `blend_mode` | How the watermark blends with the image: `normal`, `overlay`, `over`, `atop`, `xor`, `plus`, `multiply`, `burn`, `difference`, `soft_light`, `screen`, `hard_light`, `dodge`, `exclusion`, `lighten`, `darken`.   
Default: `"normal"` |
| `pattern` | Watermark repetition pattern: `single`, `grid`, `diagonal`, `random`  
Default: `"single"` |
| `pattern_allow_partial` | Allow partial watermarks at image edges  
Default: `true` |
| `pattern_max_count` | Maximum number of watermark repetitions (0 for infinite)  
Default: `50` |
| `pattern_spacing` | Spacing between repeated watermarks (in % of the target image)  
Default: `15` |
| `qrcode_enabled` | Enable QR code watermark  
Default: `false` |
| `qrcode_text` | Text to encode in QR code. Supports placeholders: `{homepage}`, `{username}`, `{topic_url}`  
Default: `""` |
| `qrcode_color` | QR code color (hex or CSS variable)  
Default: `"var(--primary)"` |
| `qrcode_background_color` | QR code background color (hex or CSS variable)  
Default: `"var(--secondary)"` |
| `qrcode_quiet_zone` | Width of white space border around QR code (0-10 modules)  
Default: `2` |
| `qrcode_error_correction` | Error correction level: `Low` (~7%), `Medium` (~15%), `Quarter` (~25%), `High` (~30%)  
More information about error correction levels can be found [here.](https://www.qrcode.com/en/about/error_correction.html)  
Default: `"Medium"` |
| `categories` | Categories where watermark should be applied.  
Default: `""` |
| `groups` | Groups the watermark should be applied to.  
Default: `"0"` |
| `skip_small_images` | Skip watermarking if image is below `min_image_dimensions`.  
Default: `false` |
| `min_image_dimensions` | Minimum dimensions required (width x height)  
Default: `"200x200"` |
| `allow_non_supported_uploads` | Allow image uploads to continue even when format is not supported  
Default: `false` |
| | |

## Watermark Types

### Image

The component supports multiple image formats: PNG, JPEG, BMP, ICO, TIFF, and WEBP.  
See the FAQ section for important information about format support limitations.

### QR Code

Generate dynamic QR codes with customizable content using these variables:

- `{homepage}` - The URL of the homepage
- `{username}` - The username of the user
- `{topic_url}` - The URL of the topic

**Important:** When styling QR code watermarks, consider contrast and sizing. Poor contrast ratios or excessive styling can make QR codes unreadable. Always test your QR code watermarks with scanning apps.

## Real-Time Preview

The settings panel includes a real-time preview feature, allowing you to see how your watermark configuration affects a sample image instantly.  
The preview window offers several interactive features:

- Resizable and movable preview window
- Option to load a random sample image
- Support for uploading your own test images from your device

On the desktop, it opens automatically. You can also open from the button at the bottom of the page:

 ![image](https://global.discourse-cdn.com/meta/original/4X/f/4/6/f4653b9bd5fa1397c6ada3aad79bfe0aeb8e827b.png)

> **More images**
>
> ![A settings page for adding a watermark and QR code to a website, showing a preview of the watermark and options to enable the QR code with different text and color settings. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/f/9/1/f9159030662103b0b7ba61be258ef33c95dcb858.jpeg)  
> ![The image shows a silhouette of two hands forming a heart shape with the sun setting in the background. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/3/2/5/32596ed6c6a0ee148508116f971c0b6d3d206a1b.jpeg)  
> ![The image shows a preview of a foggy forest scenery on a Discourse platform. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/8/b/8/8b82598f9a45a7bc13656e7b7c5e6250931d24e9.png)

## ⚠ Important Notes

- **Original Images Are Not Preserved**  
Watermarks are applied before server upload, and original images are not retained. Thoroughly test your watermark settings before deploying to production.

- If testing in the admin panel, be careful not to validate your settings immediately. I would recommend creating a group or a category to be safe.

## FAQ

**Why are image formats limited?**

_While Discourse converts all uploads to JPEG, this TC watermarking occurs pre-upload on the original format, using specific image processing libraries. While post-upload watermarking is possible, it would require multiple upload/download cycles and affect the composer experience. I’m still exploring improvements to this workflow._

**Why isn’t text watermarking supported?**

_Text watermarking would require extensive configuration options (font selection, styling, etc.) that would be difficult to implement effectively without a dedicated interface. Image watermarks provide more flexibility and can be created using existing design tools._

## Roadmap

Future development plans may include:

- Multiple watermark profiles \[1\]
- Original image preservation \[2\]
- Post-upload watermarking

## Credits

This theme component is powered by:

- [Photon](https://silvia-odwyer.github.io/photon/): A WebAssembly image processing library
- [QR Code Generator](https://www.nayuki.io/page/qr-code-generator-library): Modified [fork](https://github.com/Arkshine/qr-code-generator-wasm) with WebAssembly support.

* * *

1. The upload input is partially supported with the [Object settings type](https://meta.discourse.org/t/objects-type-for-theme-setting/305009) – it can’t be done in a TC at the moment. 

2. May require plugin development.

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 14, 2025, 9:18pm UTC](https://meta.discourse.org/t/watermark-image/347138/2 "2025-01-14T21:18:53Z")

</div>

This is the first version, and I expect missing features. I’m looking forward to any feedback! 👍

---

<div class="post-metadata">

### Author: ![ozkn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ozkn/32/196013_2.png) [@ozkn](https://meta.discourse.org/u/ozkn)
#### Post date: [January 14, 2025, 9:44pm UTC](https://meta.discourse.org/t/watermark-image/347138/3 "2025-01-14T21:44:12Z")

</div>

Thanks for the component. Does this component process images? Does this component compress images to size better than the original.

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 14, 2025, 10:01pm UTC](https://meta.discourse.org/t/watermark-image/347138/4 "2025-01-14T22:01:46Z")

</div>

The component doesn’t perform any modifications or compression apart from applying the watermark.

Discourse already preprocesses the image first (using [squoosh](https://squoosh.app/) library) → the watermark is applied → The image is uploaded to the server. That would be how it works.

---

<div class="post-metadata">

### Author: ![Monikas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/monikas/32/375316_2.png) [@Monikas](https://meta.discourse.org/u/Monikas)
#### Post date: [January 16, 2025, 7:33am UTC](https://meta.discourse.org/t/watermark-image/347138/5 "2025-01-16T07:33:56Z")

</div>

![The image shows a computer interface with three tabs displaying different pages, with a logo in the bottom right and a drop-down menu visible. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/c/a/9/ca9452cfe5bb3c634f577b5d89ed6cbeb68ac630.png)  
The first time you open a post and edit it, you can’t put a watermark on it, you need to post it and then click edit post and upload a picture to put a watermark on it.  
The theme used is [FKB Pro - Social theme - #375 by MihirR](https://meta.discourse.org/t/fkb-pro-social-theme/234323/375)

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 16, 2025, 1:05pm UTC](https://meta.discourse.org/t/watermark-image/347138/6 "2025-01-16T13:05:14Z")

</div>

You mean that if you open/edit an existing post for the first time and upload an image, there is no watermark. Is this correct? Can you reproduce it every time? Do you see any error in the browser’s console?

If I understand correctly, you expect an existing uploaded image (before this TC installation) to have a watermark when you edit the post (or have a way to watermark the image manually) . It doesn’t work this way. You need to upload the image to apply a watermark.

Having a button to watermark a selected image manually could be a feature. Would that work with you?

---

<div class="post-metadata">

### Author: ![Monikas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/monikas/32/375316_2.png) [@Monikas](https://meta.discourse.org/u/Monikas)
#### Post date: [January 16, 2025, 10:40pm UTC](https://meta.discourse.org/t/watermark-image/347138/7 "2025-01-16T22:40:30Z")

</div>

It’s the images uploaded after creating a new post that don’t have a watermark It’s the images uploaded after going into the post after posting and clicking edit that have the watermark.

For the posting button I use [Compose Center - #13](https://meta.discourse.org/t/compose-center/323776/13)

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 16, 2025, 10:49pm UTC](https://meta.discourse.org/t/watermark-image/347138/8 "2025-01-16T22:49:09Z")

</div>

Can you make a quick video, please? That would be useful to see and understand what’s happening.

---

<div class="post-metadata">

### Author: ![Monikas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/monikas/32/375316_2.png) [@Monikas](https://meta.discourse.org/u/Monikas)
#### Post date: [January 17, 2025, 3:14am UTC](https://meta.discourse.org/t/watermark-image/347138/9 "2025-01-17T03:14:15Z")

</div>



---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 17, 2025, 1:36pm UTC](https://meta.discourse.org/t/watermark-image/347138/10 "2025-01-17T13:36:35Z")

</div>

Thanks for your patience! I’ve found the issue. It should be fixed now! 👍

---

<div class="post-metadata">

### Author: ![thaidb](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thaidb/32/68488_2.png) [@thaidb](https://meta.discourse.org/u/thaidb)
#### Post date: [January 20, 2025, 12:25am UTC](https://meta.discourse.org/t/watermark-image/347138/11 "2025-01-20T00:25:22Z")

</div>

I get this error when install this component

`Đã xảy ra lỗi: Error creating upload asset: worker_photon_wasm. Original filename Sorry, the file you are trying to upload is not authorized (authorized extensions: jpg, jpeg, png, woff, woff2, svg, eot, ttf, otf, gif, js, dwg).`

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 20, 2025, 12:55am UTC](https://meta.discourse.org/t/watermark-image/347138/12 "2025-01-20T00:55:16Z")

</div>

That’s odd. What is your Discourse version?  
You can try to add `wasm` extension in the allowed lists, but it works fine in my local and two production installations without any changes. 🤔

---

<div class="post-metadata">

### Author: ![Monikas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/monikas/32/375316_2.png) [@Monikas](https://meta.discourse.org/u/Monikas)
#### Post date: [January 22, 2025, 5:39am UTC](https://meta.discourse.org/t/watermark-image/347138/13 "2025-01-22T05:39:05Z")

</div>

I’m going to give you some feedback, I don’t know what’s going on, but it seems that Chinese users don’t have watermarks on their uploaded images.

But I’m using a newly created account with that no-trace mode turned on and it’s working, so I don’t know what the problem is.

 ![The image features collaged content of a person in various outfits, with some images blurred or pixelated, displayed alongside smaller profile pictures of individuals. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/8/a/1/8a1dac57e20acdeda3768456e04cccd68c5add2d.jpeg)

 ![The image shows two posts from a user named "范大爷" on a website, featuring cosplay images of two different characters with detailed descriptions in Chinese. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/6/4/9/6493ed7a2c659f8d3c35806e3f459623a3cc50fa.jpeg)

Sometimes it works, sometimes it doesn’t.

Take down the images are .jpeg .png But just like the picture in the video I copy the picture and upload it and it’s watermarked so I don’t know what the problem is.

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [January 22, 2025, 6:58pm UTC](https://meta.discourse.org/t/watermark-image/347138/14 "2025-01-22T18:58:06Z")

</div>

Thanks for the feedback!

For you, no matter how you try, it always works, right?

Can you ask some of your users to check the browser’s console if it happens and copy any error message they see to you? Also, whether they are using a mobile device (android, iphone, etc) - If they can explain what they did exactly to see if it can help, it would be welcome.

It doesn’t look like an issue with the image itself if you are able to watermark the image yourself later. What is left is either an error in the code like the previous issue, or an error in the watermarking process. Unfortunately, I can’t reproduce it no matter I do.

I will see to update the component later to make sure any errors are caught and displayed to the user.

---

<div class="post-metadata">

### Author: ![LaptechInfo](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LaptechInfo](https://meta.discourse.org/u/LaptechInfo)
#### Post date: [February 14, 2025, 2:10am UTC](https://meta.discourse.org/t/watermark-image/347138/15 "2025-02-14T02:10:26Z")

</div>

Hi, thank you for making this component.  
when I tried to upload watermark photo, this error comes, i tried JPEG, Webp also, but still no luck

**My Discourse forum is UpToDate**

 ![The image displays an error message on a webpage regarding theme settings, specifically stating that an error has occurred when attempting to set a watermark image, with an option to reset settings to default. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/b/f/0/bf0d8ab1e95cee901b8114948179cb0f62ab77f1.png)

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [February 14, 2025, 2:15am UTC](https://meta.discourse.org/t/watermark-image/347138/16 "2025-02-14T02:15:11Z")

</div>

Hi @LaptechInfo

That’s strange. At this point, the TC should do nothing. This is the standard upload setting.  
Can you look at the browser’s console and see if you see any error messages?

Is it possible to provide an image that fails so I can test on my side as well?

---

<div class="post-metadata">

### Author: ![LaptechInfo](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LaptechInfo](https://meta.discourse.org/u/LaptechInfo)
#### Post date: [February 14, 2025, 3:53am UTC](https://meta.discourse.org/t/watermark-image/347138/17 "2025-02-14T03:53:01Z")

</div>

Hi, I tried many images randomly, but none of them worked.  
I am not a programmer, no knowledge in any computer languages.  
try this image, I tired.  
[laptechinfo webp.zip](https://meta.discourse.org/uploads/short-url/pT4RPebLkFkYy4jWS4wzeqe1EWh.zip) (558 Bytes)  
[watermark.zip](https://meta.discourse.org/uploads/short-url/youXVQk6viAMWn07gdhCNDXbfkJ.zip) (257.7 KB)

 ![The image shows a web development interface with options to adjust theme settings and an error message regarding the watermark image for an image upload feature in a project named "aShoppersChain". (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/1/2/8/1280784c48e53a7bdb739d82e6ff677518a45a5c.png)

@Arkshine

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [February 14, 2025, 4:05am UTC](https://meta.discourse.org/t/watermark-image/347138/18 "2025-02-14T04:05:48Z")

</div>

Thanks! Can you also show the content of your Console? The tab right after. I think it might help.

EDIT: I think I can reproduce it, let me see, and will get back to you soon!

---

<div class="post-metadata">

### Author: ![LaptechInfo](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LaptechInfo](https://meta.discourse.org/u/LaptechInfo)
#### Post date: [February 14, 2025, 4:16am UTC](https://meta.discourse.org/t/watermark-image/347138/19 "2025-02-14T04:16:18Z")

</div>

Console tab

 ![The image shows a Jupyter notebook displaying code related to a Discourse forum deprecation warning, including a console error about deprecation notices and failed resources across multiple elements. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/8/c/5/8c587a70178e2e056c04a672d94fea0b669743c0.png)  
@Arkshine

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [February 14, 2025, 5:37am UTC](https://meta.discourse.org/t/watermark-image/347138/20 "2025-02-14T05:37:18Z")

</div>

@LaptechInfo Thanks! There is a bug in Discourse from a PR yesterday. I made a topic: [Can't upload image in settings](https://meta.discourse.org/t/cant-upload-image-in-settings/352213). 👍

[Next page](https://meta.discourse.org/t/watermark-image/347138.md?page=2)
