惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
I
Intezer
Y
Y Combinator Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
Netflix TechBlog - Medium
The Hacker News
The Hacker News
AWS News Blog
AWS News Blog
aimingoo的专栏
aimingoo的专栏
A
About on SuperTechFans
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Stack Overflow Blog
Stack Overflow Blog
Hacker News: Ask HN
Hacker News: Ask HN
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog
T
Tor Project blog
C
Cybersecurity and Infrastructure Security Agency CISA
云风的 BLOG
云风的 BLOG
博客园_首页
V2EX - 技术
V2EX - 技术
T
Threat Research - Cisco Blogs
腾讯CDC
宝玉的分享
宝玉的分享
博客园 - 叶小钗
罗磊的独立博客
S
Securelist
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
Scott Helme
Scott Helme
博客园 - 司徒正美
W
WeLiveSecurity
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Secure Thoughts
NISL@THU
NISL@THU
N
News and Events Feed by Topic
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
K
Kaspersky official blog
IT之家
IT之家

Homepage on Aditya Telange

One Year with evil-winrm-py - A Retrospective Bypassing LinkedIn's Connection Privacy with a Simple Search Filter Making Dynamic Instrumentation Accessible with Frida UI Breaking Payload Encryption in Web Applications HackTheBox (HTB) - Escape HackTheBox (HTB) - Resolute HackTheBox (HTB) - Certified State of VMWare Workstation (Pro?) on Linux Android App Security Testing Lab with MobSleuth Android phone as a Webcam on Linux Breaking down Reverse shell commands HackTheBox (HTB) - Photobomb Merging AOSP Security Patches into Custom ROMs Primer on HTTP Security Headers Image Zoom-In effect with HUGO HackTheBox (HTB) - Legacy HackTheBox (HTB) - Lame Cryptohack - Keyed Permutations [5 pts] Cryptohack - Resisting Bruteforce [10 pts] Cryptohack - RSA Starter 1 [10 pts] Cryptohack - Base64 [10 pts] Cryptohack - Bytes and Big Integers [10 pts] Cryptohack - Hex [5 pts] Cryptohack- XOR Starter [10 pts] HackTheBox (HTB) - Horizontall HackTheBox (HTB) - Forge HackTheBox (HTB) - Previse HackTheBox (HTB) - BountyHunter HackTheBox (HTB) - Explore HackTheBox (HTB) - Cap HackTheBox (HTB) - Pit HackTheBox (HTB) - Knife HackTheBox (HTB) - Love HackTheBox (HTB) - Tenet HackTheBox (HTB) - Ready My Github Project went viral! Cryptohack - ASCII [5 pts] Cryptohack - Finding Flags [2 pts] Cryptohack - Great Snakes [3 pts] Cryptohack - JWT Sessions [10 pts] Cryptohack - Network Attacks [5 pts] Cryptohack - Token Appreciation [5 pts] CAF's Android for MSM Basic Website Analytics with Vercel Github Actions as Temporary File Sharing Platform Addition of prebuilt APK - AOSP Rom Development External Link With target='_blank' in Hugo Markdown Setting Up Build Environment - AOSP Rom Development Getting Started - AOSP Rom Development Using Secure HTTP Headers with Vercel/Zeit Education and Certifications Link Tree ↟ | Aditya Telange Personal Projects Resume - Aditya Telange Security Acknowledgements About Me Graph View License Privacy Policy
Watermarking images with HUGO
[Aditya Telange](https://x.com/adityatelange) · 2021-04-24 · via Homepage on Aditya Telange

Introduction

Watermarking is the process of superimposing a logo or piece of text atop a document or image file, and it’s an important process when it comes to both the copyright protection and marketing of digital works.1

Adding a watermark to our work ensures that if anything we make ends up going viral, our brand is recognized.

Watermarking also ensures that people do not use these images without referring to the “original publisher”.

Hugo is an open-source static site generator i.e. SSG written in Go. Hugo is for people who want to hard code their website without worrying about setting up complicated runtimes, dependencies and databases.


Let’s get started 🚀

From HUGO v0.80.0 they have added support for overlay images, with which we can add watermark. So, ensure you have v0.80 or greater installed on your system.

You can check that by typing hugo version in your Terminal or Command prompt.

Now, we will be dealing here with “in-post images”, that is images that are inside a blog post. For theme-specific images such as Cover Images, Header Images you need to modify the code slightly for this to work.

For the scope of this article, we will add the watermark to the right bottom corner images.

Let’s understand the basics

About Page Bundles 🗐

For our implementation to work we need to use Page Bundles

HUGO has a term called Page Resources which are only accessible from Page Bundles and this is essential for getting the image we want to add a Watermark to!

Page resources contain images, documents, etc. and have page-relative URLs and their metadata.

So for “Page Bundling” to work your site’s content folder should look similar to:

* (site-root)
├── content
│   ├── post-one
│   │   ├── index.md
│   │   └── images
│   │       ├── image_one.jpeg
│   │       ├── image_two.jpeg
│   │       └── image_three.jpeg
│   └── post-two
│       ├── index.md
│       └── images
│           └── image_one.jpeg
└── themes

Okay so basically for the above site, post-one has all the files inside its directory, which can be called “Page Resources”. So index.md and the images under images directory can be fetched with and processed as per our needs with the help of the Bundled resources.

About the Logo image 🎞️

As of writing this post, we can only add an overlay of an image over another image and not text over the image.

So we have to 1st get the image (called ’logo image’ henceforth) we want to add as a watermark and place it in the desired location under assets directory so that it could be accessible by HUGO’s resource handler.

For this tutorial, we’ll place the logo image at ./assets/images/logo.png.

About Markdown Render Hooks 🪝

Hugo offers really handy Markdown Render Hooks. These allow custom templates to override markdown rendering functionality.

We will be using render-image hook to process out the images in the post as per our needs.

The render-image hook stays in the location shown below.

* (site root)
├── layouts
│   └── _default
│       └── _markup
│           └── render-image.html
└── themes

The code snippet </>

We will be using the following code into render-image.html which will add a watermark(an image at ./assets/images/logo.png) at the right bottom corner of the original image.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!-- contents of render-image.html -->
{{- $link := split .Destination "#" }}
{{- $image := (.Page.Resources.ByType "image").GetMatch (printf "*%s*" (index $link 0)) }}
{{- $logo := (resources.Get "images/logo.png") }}

{{- if and $image $logo }}
{{- $size := math.Round (mul $image.Height 0.30) }}
{{- $size := cond (ge $size 80) ($size) (80.0) }}

{{- $logo := $logo.Resize (printf "%.0fx jpg" $size) }}
{{- $image := $image.Filter (images.Overlay $logo (sub $image.Width $logo.Width) (sub $image.Height $logo.Height) ) }}
{{- $finalUrl := cond (isset $link 1) (printf "%s#%s" ($image.Permalink) (index $link 1)) ($image.Permalink) -}}

<img src="{{ $finalUrl | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}" {{ end }} />
{{- else }}
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}" {{ end }} />
{{- end }}

✨ I’ll be updating the code here so that it uses dynamic values and adds a decent-sized watermark for images of multiple sizes. GitHub Gist Link

Code explanation 🗣️

  • The render-image markdown-hook has these variables with it, of which the .Destination variable gives us the path to the resource (in our case, image).

  • We split the image path into 2 parts, with # as the delimiter, so that the resource path does not have any extra text attached with it. Then we get the actual image resource and store it in $image.

  • We then get the image we want as a watermark and store it into $logo.

  • Then we check whether both $image and $logo aren’t empty then proceed to watermarking, else we display the original image as it is with .Destination.

  • Now that both $image and $logo are present we make some calculations so that the size of the watermark is decent, not huge not so small! We’ll not look into that part of the code as it out-of-scope for this blog.

  • The line below is where we tell HUGO to add the watermark($logo) over the image.

    {{- $image := $image.Filter (images.Overlay $logo (sub $image.Width $logo.Width) (sub $image.Height $logo.Height) ) }}
    
    • images.Overlay takes 3 arguments: image resource, position on x-axis, position on y-axis

    • Now as we want to add the logo to the right bottom corner, we’ll set the X and Y-axis of the logo image such that it will fit into the place.

    • For this we subtract the Width of logo from image’s Width, same goes for Height, we subtract the Height of logo from image’s Height.

      position on X = $image.Width- $logo.Width
      
      position on Y = $image.Height - $logo.Height
      
  • We then use Filter function to add the overlay over the original image.

  • Now with HUGO magic 🪄 we have a nicely watermarked image with the logo we want!

  • Finally, we will add the params we initially removed from the URL, and add those back after the # and store the image’s URL in $finalUrl. Then add a link to the generated image with the template.


Results 🖼️

As you can see in the image below, we have a watermark adityatelange.in (the logo image) in right bottom corner just by using the regular markdown syntax. 🎉

![Sample Results](media/images/sample.jpg#center "Sample Result with a watermark")

Turns into ↓

Sample Results