<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Michael Muratov</title><link>https://michaelmuratov.com/categories/security/</link><description>Recent content on Michael Muratov</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 25 May 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://michaelmuratov.com/categories/security/index.xml" rel="self" type="application/rss+xml"/><item><title>Intro to Image Watermarking</title><link>https://michaelmuratov.com/blog/artifacts/guides/intro-image-watermarking/</link><pubDate>Sun, 25 May 2025 00:00:00 +0000</pubDate><guid>https://michaelmuratov.com/blog/artifacts/guides/intro-image-watermarking/</guid><description>&lt;h3 id="intro-to-image-watermarking"&gt;Intro to Image Watermarking&lt;/h3&gt;
&lt;p&gt;Watermarking is a technique used to embed information into an image, which can be used for various purposes such as copyright protection, authentication, or non-repudiation. In this guide, we will explore the basics of image watermarking and how you can implement it in your projects.&lt;/p&gt;
&lt;h4 id="why-use-watermarking"&gt;Why Use Watermarking?&lt;/h4&gt;
&lt;link href="https://michaelmuratov.com/css/admonitions.min.css" rel="stylesheet" /&gt;
&lt;div class="admonition task"&gt;
&lt;div class="admonition-header"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path d="M152.1 38.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 113C-2.3 103.6-2.3 88.4 7 79s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zm0 160c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 273c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zM224 96c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zm0 160c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zM160 416c0-17.7 14.3-32 32-32l288 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-288 0c-17.7 0-32-14.3-32-32zM48 368a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"/&gt;&lt;/svg&gt;
&lt;span&gt;Watermarking serves several purposes:&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;&lt;strong&gt;Copyright protection:&lt;/strong&gt;&lt;br&gt;
Watermarks can help protect your images from unauthorized use by clearly indicating ownership.&lt;/p&gt;</description><content:encoded><![CDATA[<h3 id="intro-to-image-watermarking">Intro to Image Watermarking</h3>
<p>Watermarking is a technique used to embed information into an image, which can be used for various purposes such as copyright protection, authentication, or non-repudiation. In this guide, we will explore the basics of image watermarking and how you can implement it in your projects.</p>
<h4 id="why-use-watermarking">Why Use Watermarking?</h4>


<link href="/css/admonitions.min.css" rel="stylesheet" />
  <div class="admonition task">
    <div class="admonition-header">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M152.1 38.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 113C-2.3 103.6-2.3 88.4 7 79s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zm0 160c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 273c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zM224 96c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zm0 160c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zM160 416c0-17.7 14.3-32 32-32l288 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-288 0c-17.7 0-32-14.3-32-32zM48 368a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"/></svg>
      <span>Watermarking serves several purposes:</span>
    </div>
      <div class="admonition-content">
        <p><strong>Copyright protection:</strong><br>
Watermarks can help protect your images from unauthorized use by clearly indicating ownership.</p>
<p><strong>Authentication:</strong><br>
Watermarks can be used to verify the authenticity of an image, ensuring that it has not been tampered with.</p>
<p><strong>Branding:</strong><br>
Adding a logo or signature to your images can help promote your brand and increase recognition.</p>
<p><strong>Non-repudiation:</strong><br>
Watermarks can provide proof of ownership or authorship, making it difficult for others to deny their use of the image.</p>
      </div>
  </div><h4 id="basic-techniques-for-watermarking">Basic Techniques for Watermarking</h4>
<h5 id="1-visible-watermarking">1. Visible Watermarking</h5>
<p>One of the simplest methods of watermarking is to alter the pixel values of an image. This is usually done for copyright protection or branding purposes. The watermark can be a logo, text, or any other image that is blended with the original image. This type of watermarking is immediately noticeable and can be readily removed by someone with image editing skills, but it serves as a visible deterrent against unauthorized use.</p>

<div><img src="shutterstock_watermark.jpg" 
		 class="img-preset img-preset-md img-fluid" alt="Prompting Flow">
</div>

<h5 id="2-least-significant-bit-lsb-insertion">2. Least Significant Bit (LSB) Insertion</h5>
<p>Least significant bit insertion is a subset of steganography where a hidden message is imbedded into an image to bypass detection. The simplest method involves modifying the least significant bits (LSBs) of pixel values, which allows for a more robust and imperceptible watermark.</p>

<div><img src="lsb.png" 
		 class="img-preset img-preset-md">
</div>

<h5 id="3-frequency-domain-manipulation">3. Frequency Domain Manipulation</h5>
<p>This method involves transforming the image into the frequency domain using techniques like the Discrete Cosine Transform (DCT) or Discrete Wavelet Transform (DWT). Watermarks can then be embedded in the frequency coefficients, which are not visible to the human eye.</p>
<p>These techniques are more complex but provide better security and robustness against attacks such as cropping, resizing, or compression. We will cover the DWT in a more advanced quide.</p>

<div><img src="dwt.png" 
		 class="img-preset img-preset-md img-fluid">

	<figcaption style="margin:0px;" class="figure-caption">
		https://www.intechopen.com/chapters/18615
	</figcaption>
</div>

<h3 id="least-significant-bit-watermarking">Least Significant Bit Watermarking</h3>
<p>To implement the simplest form of invisible watermarking in your images, you can use the cv2 library in Python to read in the image and modify the last bits of each pixel.</p>






<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 1</span><span><span style="color:#94e2d5">import</span> <span style="color:#fab387">cv2</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 2</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 3</span><span><span style="color:#cba6f7">def</span> <span style="color:#89b4fa">embed_lsb</span>(image_path, message, output_path):
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 4</span><span>    image <span style="color:#89dceb;font-weight:bold">=</span> cv2<span style="color:#89dceb;font-weight:bold">.</span>imread(image_path)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 5</span><span>    flat <span style="color:#89dceb;font-weight:bold">=</span> image<span style="color:#89dceb;font-weight:bold">.</span>flatten()
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 6</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 7</span><span>    <span style="color:#6c7086;font-style:italic"># Convert message to binary</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 8</span><span>    bits <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">&#39;&#39;</span><span style="color:#89dceb;font-weight:bold">.</span>join([<span style="color:#89dceb">format</span>(<span style="color:#89dceb">ord</span>(i), <span style="color:#a6e3a1">&#39;08b&#39;</span>) <span style="color:#cba6f7">for</span> i <span style="color:#89dceb;font-weight:bold">in</span> message]) <span style="color:#89dceb;font-weight:bold">+</span> <span style="color:#a6e3a1">&#39;00000000&#39;</span>  <span style="color:#6c7086;font-style:italic"># Null terminator</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 9</span><span>    <span style="color:#cba6f7">for</span> i <span style="color:#89dceb;font-weight:bold">in</span> <span style="color:#89dceb">range</span>(<span style="color:#89dceb">len</span>(bits)):
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">10</span><span>        flat[i] <span style="color:#89dceb;font-weight:bold">=</span> (flat[i] <span style="color:#89dceb;font-weight:bold">&amp;</span> <span style="color:#89dceb;font-weight:bold">~</span><span style="color:#fab387">1</span>) <span style="color:#89dceb;font-weight:bold">|</span> <span style="color:#89dceb">int</span>(bits[i])  <span style="color:#6c7086;font-style:italic"># Set LSB</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">11</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">12</span><span>    watermarked <span style="color:#89dceb;font-weight:bold">=</span> flat<span style="color:#89dceb;font-weight:bold">.</span>reshape(image<span style="color:#89dceb;font-weight:bold">.</span>shape)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">13</span><span>    cv2<span style="color:#89dceb;font-weight:bold">.</span>imwrite(output_path, watermarked)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">14</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">15</span><span><span style="color:#cba6f7">def</span> <span style="color:#89b4fa">extract_lsb</span>(image_path):
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">16</span><span>    <span style="color:#6c7086;font-style:italic"># Load image and flatten to 1D array</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">17</span><span>    image <span style="color:#89dceb;font-weight:bold">=</span> cv2<span style="color:#89dceb;font-weight:bold">.</span>imread(image_path)<span style="color:#89dceb;font-weight:bold">.</span>flatten()
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">18</span><span>    bits <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">&#34;&#34;</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">19</span><span>    <span style="color:#cba6f7">for</span> byte <span style="color:#89dceb;font-weight:bold">in</span> image:
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">20</span><span>        bits <span style="color:#89dceb;font-weight:bold">+=</span> <span style="color:#89dceb">str</span>(byte <span style="color:#89dceb;font-weight:bold">&amp;</span> <span style="color:#fab387">1</span>)  <span style="color:#6c7086;font-style:italic"># Get LSB</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">21</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">22</span><span>        <span style="color:#6c7086;font-style:italic"># Check every 8 bits for null terminator</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">23</span><span>        <span style="color:#cba6f7">if</span> <span style="color:#89dceb">len</span>(bits) <span style="color:#89dceb;font-weight:bold">%</span> <span style="color:#fab387">8</span> <span style="color:#89dceb;font-weight:bold">==</span> <span style="color:#fab387">0</span>:
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">24</span><span>            char <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#89dceb">chr</span>(<span style="color:#89dceb">int</span>(bits[<span style="color:#89dceb;font-weight:bold">-</span><span style="color:#fab387">8</span>:], <span style="color:#fab387">2</span>))
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">25</span><span>            <span style="color:#cba6f7">if</span> char <span style="color:#89dceb;font-weight:bold">==</span> <span style="color:#a6e3a1">&#39;</span><span style="color:#89b4fa">\x00</span><span style="color:#a6e3a1">&#39;</span>:
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">26</span><span>                <span style="color:#cba6f7">break</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">27</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">28</span><span>    <span style="color:#6c7086;font-style:italic"># Convert full bitstring to characters (excluding null terminator)</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">29</span><span>    message <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">&#39;&#39;</span><span style="color:#89dceb;font-weight:bold">.</span>join(
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">30</span><span>        <span style="color:#89dceb">chr</span>(<span style="color:#89dceb">int</span>(bits[i:i<span style="color:#89dceb;font-weight:bold">+</span><span style="color:#fab387">8</span>], <span style="color:#fab387">2</span>)) <span style="color:#cba6f7">for</span> i <span style="color:#89dceb;font-weight:bold">in</span> <span style="color:#89dceb">range</span>(<span style="color:#fab387">0</span>, <span style="color:#89dceb">len</span>(bits)<span style="color:#89dceb;font-weight:bold">-</span><span style="color:#fab387">8</span>, <span style="color:#fab387">8</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">31</span><span>    )
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">32</span><span>    <span style="color:#cba6f7">return</span> message
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">33</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">34</span><span><span style="color:#cba6f7">if</span> <span style="color:#f5e0dc">__name__</span> <span style="color:#89dceb;font-weight:bold">==</span> <span style="color:#a6e3a1">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">35</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">36</span><span>    <span style="color:#6c7086;font-style:italic"># Example usage</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">37</span><span>    embed_lsb(<span style="color:#a6e3a1">&#34;image.png&#34;</span>, <span style="color:#a6e3a1">&#34;Secret Watermark&#34;</span>, <span style="color:#a6e3a1">&#34;output.png&#34;</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">38</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">39</span><span>    message <span style="color:#89dceb;font-weight:bold">=</span> extract_lsb(<span style="color:#a6e3a1">&#34;image.png&#34;</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">40</span><span>    <span style="color:#89dceb">print</span>(<span style="color:#a6e3a1">&#34;Extracted message:&#34;</span>, message)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">41</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">42</span><span>    message <span style="color:#89dceb;font-weight:bold">=</span> extract_lsb(<span style="color:#a6e3a1">&#34;output.png&#34;</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">43</span><span>    <span style="color:#89dceb">print</span>(<span style="color:#a6e3a1">&#34;Extracted message:&#34;</span>, message)</span></span></code></pre></div>
<p>The <code>embed_lsb</code> function will take an image, a message, and an output path to save the watermarked image. The <code>extract_lsb</code> function will read the watermarked image and extract the hidden message. There are simpler was of doing this such as using a dedicated steganography library like <code>stegano</code>, but this example shows how you can implement it from scratch.</p>
<h4 id="stegano-code-example">Stegano Code Example</h4>






<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 1</span><span><span style="color:#94e2d5">from</span> <span style="color:#fab387">stegano</span> <span style="color:#94e2d5">import</span> lsb
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 2</span><span><span style="color:#cba6f7">def</span> <span style="color:#89b4fa">embed_message</span>(image_path, message, output_path):
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 3</span><span>    <span style="color:#6c7086;font-style:italic"># Embed the message in the image</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 4</span><span>    watermarked_image <span style="color:#89dceb;font-weight:bold">=</span> lsb<span style="color:#89dceb;font-weight:bold">.</span>hide(image_path, message)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 5</span><span>    watermarked_image<span style="color:#89dceb;font-weight:bold">.</span>save(output_path)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 6</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 7</span><span><span style="color:#cba6f7">def</span> <span style="color:#89b4fa">extract_message</span>(image_path):
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 8</span><span>    <span style="color:#6c7086;font-style:italic"># Extract the message from the image</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c"> 9</span><span>    <span style="color:#cba6f7">return</span> lsb<span style="color:#89dceb;font-weight:bold">.</span>reveal(image_path)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">10</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">11</span><span><span style="color:#cba6f7">if</span> <span style="color:#f5e0dc">__name__</span> <span style="color:#89dceb;font-weight:bold">==</span> <span style="color:#a6e3a1">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">12</span><span>    embed_message(<span style="color:#a6e3a1">&#34;image.png&#34;</span>, <span style="color:#a6e3a1">&#34;Secret Watermark&#34;</span>, <span style="color:#a6e3a1">&#34;watermarked_image.png&#34;</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">13</span><span>    message <span style="color:#89dceb;font-weight:bold">=</span> extract_message(<span style="color:#a6e3a1">&#34;watermarked_image.png&#34;</span>)
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c">14</span><span>    <span style="color:#89dceb">print</span>(<span style="color:#a6e3a1">&#34;Extracted message:&#34;</span>, message)</span></span></code></pre></div>
<p>This is a much simpler way to achieve the same result and it abstracts away the details of how the LSB is manipulated. The <code>stegano</code> library handles the encoding and decoding of messages in images, making it easier to implement watermarking without needing to understand the underlying pixel manipulation. There are also other modules within stegano that allow for more complex watermarking techniques, such as using different color channels or even embedding multiple messages.</p>
<h3 id="watermarking-example">Watermarking Example</h3>








<div style="
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1.5rem;
  align-items: start;
">
 


<div><img src="portrait.png" 
		 class="img-preset img-preset-md img-fluid">

	<figcaption style="margin:0px;" class="figure-caption">
		Original Image
	</figcaption>
</div>



<div><img src="watermarked_portrait.png" 
		 class="img-preset img-preset-md img-fluid">

	<figcaption style="margin:0px;" class="figure-caption">
		Watermarked Image
	</figcaption>
</div>



</div>

<h3 id="reading-the-watermark">Reading the Watermark</h3>
<p>To read the watermark from an image, you can reverse the process by extracting the pixel values or frequency coefficients where the watermark was embedded. This can be done using similar libraries and techniques as mentioned above.</p>
<h4 id="using-the-extract_lsb-function">Using the <code>extract_lsb</code> function</h4>


<link href="/css/admonitions.min.css" rel="stylesheet" />
  <div class="admonition success">
    <div class="admonition-header">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>
      <span>Results</span>
    </div>
      <div class="admonition-content">
        <p><strong>Original Image Text:</strong><br>
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ</p>
<p><strong>Watermarked Image Text:</strong><br>
Secret Watermark</p>
      </div>
  </div>]]></content:encoded></item></channel></rss>