{"id":28209,"date":"2022-05-24T11:42:25","date_gmt":"2022-05-24T11:42:25","guid":{"rendered":"http:\/\/hiding-text-in-images-using-plain-javascript"},"modified":"2025-02-16T10:19:38","modified_gmt":"2025-02-16T18:19:38","slug":"hiding-text-in-images-using-plain-javascript","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/","title":{"rendered":"Hiding Text in Images Using Plain JavaScript"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript, we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let\u2019s explore how we can achieve this.<\/p>\n<h2>Codesandbox<\/h2>\n<p>The final version of this project can be viewed on  <a href=\"https:\/\/codesandbox.io\/s\/js-stagnography-w4eyef\">Codesandbox<\/a>.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/js-stagnography-w4eyef?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"js-stagnography\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><h2>Github<\/h2>\n<p>Check out the complete source code in this  <a href=\"https:\/\/github.com\/musebe\/js-stagnography\">GitHub Repository<\/a>.<\/p>\n<h2>Pre-requisites<\/h2>\n<p>To follow along through this article you are required to have:<\/p>\n<ul>\n<li>Basic knowledge of HTML<\/li>\n<li>Knowledge of Javascript<\/li>\n<li>Some knowledge of Bootstrap<\/li>\n<\/ul>\n<h2>Introduction<\/h2>\n<p>We will be using a JavaScript library by Peter Eigenschink <a href=\"https:\/\/www.peter-eigenschink.at\/projects\/steganographyjs\/\">steganography.js<\/a> to build our project. You can download the library <a href=\"https:\/\/www.peter-eigenschink.at\/projects\/steganographyjs\/\">here<\/a>. This library offers two great functions to decode and encode text in images and abstracts the code behind these functions.<\/p>\n<ul>\n<li>\n<code>encode<\/code> takes a message as a String and an image as Image, HTMLImageElement, or String representing the data-URL of the cover image. Returns the data-URL of the image with the encoded message inside.<\/li>\n<li>\n<code>decode<\/code> takes an image as Image, HTMLImageElement, or String representing the data-URL of the image and returns the message which was found in the image.<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">git <span class=\"hljs-keyword\">clone<\/span> https:<span class=\"hljs-comment\">\/\/github.com\/musebe\/js-stagnography<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h2>Usage<\/h2>\n<p>After cloning you can open the <code>index.html<\/code> file in your browser. Make sure the <code>steganography.min.js<\/code> from the library downloaded is in your js folder. Now let\u2019s examine the <code>scripts.js<\/code> file.<\/p>\n<h3>Writing the handleFileSelect to handle uploaded image<\/h3>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleFileSelect<\/span>(<span class=\"hljs-params\">evt<\/span>) <\/span>{\n    <span class=\"hljs-keyword\">var<\/span> original = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"original\"<\/span>),\n        stego = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"stego\"<\/span>),\n        img = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"img\"<\/span>),\n        cover = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"cover\"<\/span>),\n        message = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"message\"<\/span>);\n    <span class=\"hljs-keyword\">if<\/span>(!original || !stego) <span class=\"hljs-keyword\">return<\/span>;\n    <span class=\"hljs-keyword\">var<\/span> files = evt.target.files; \n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">var<\/span> i = <span class=\"hljs-number\">0<\/span>, f; f = files&#91;i]; i++) {\n        <span class=\"hljs-keyword\">if<\/span> (!f.type.match(<span class=\"hljs-string\">'image.*'<\/span>)) {\n            <span class=\"hljs-keyword\">continue<\/span>;\n        }\n        <span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n        reader.onload = (<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">theFile<\/span>) <\/span>{\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">e<\/span>) <\/span>{\n                img.src = e.target.result;\n                img.title = <span class=\"hljs-built_in\">escape<\/span>(theFile.name);\n                stego.className = <span class=\"hljs-string\">\"half invisible\"<\/span>;\n                cover.src = <span class=\"hljs-string\">\"\"<\/span>;\n                message.innerHTML=<span class=\"hljs-string\">\"\"<\/span>;\n                message.parentNode.className=<span class=\"hljs-string\">\"invisible\"<\/span>;\n                updateCapacity();\n            };\n        })(f);\n        reader.readAsDataURL(f);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ul>\n<li>\n<p><code>handleFileSelect(evt){...}<\/code>this function first returns the elements with their specific values required for our project and stores them in appropriate variables so they can be easily referenced in our function.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">var<\/span> original = <span class=\"hljs-built_in\">document<\/span>.getElementById (<span class=\"hljs-string\">\"original\"<\/span>),\n    stego = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"stego\"<\/span>),\n    img = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"img\"<\/span>),\n    cover = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"cover\"<\/span>),\n    message = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"message\"<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<li>\n<p>if the value in <code>original<\/code> and <code>stego<\/code> is <code>null<\/code> it should return nothing.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">if<\/span>(!original || !stego) <span class=\"hljs-keyword\">return<\/span>;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<li>\n<p>To access the list of files where <code>type='file'<\/code> using the <code>target.files<\/code><\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">var<\/span> files = evt.target.files;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We are going to loop the list of files and make sure that the files we are to process are of type image<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">  <span class=\"hljs-keyword\">if<\/span> (!f.type.match(<span class=\"hljs-string\">'image.*'<\/span>)) {\n      <span class=\"hljs-keyword\">continue<\/span>;\n  }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>To read data from an image which is a Binary Large Object(BLOB) we need to create an object of type FileReader<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><code>load<\/code> is one of the events triggered in process of reading the file. When the image loads we are going to capture the information on it and set some classes to some of our elements.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">reader.onload = (<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">theFile<\/span>) <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">e<\/span>) <\/span>{\n        img.src = e.target.result;\n        img.title = <span class=\"hljs-built_in\">escape<\/span>(theFile.name);\n        stego.className = <span class=\"hljs-string\">\"half invisible\"<\/span>;\n        cover.src = <span class=\"hljs-string\">\"\"<\/span>;\n        message.innerHTML=<span class=\"hljs-string\">\"\"<\/span>;\n        message.parentNode.className=<span class=\"hljs-string\">\"invisible\"<\/span>;\n        updateCapacity();\n    };\n})(f);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<li>\n<p>When the uploaded file loads we want to render the uploaded image to the left to make the encoded image and the message section <code>invisible<\/code> It also checks whether the tags with an id of <code>img<\/code> and <code>text<\/code> have values and computes the number of characters in the textarea field by invoking the <code>updateCapacity()<\/code> function as shown above.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updateCapacity<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n        <span class=\"hljs-keyword\">var<\/span> img = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'img'<\/span>),\n            textarea = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'text'<\/span>);\n        <span class=\"hljs-keyword\">if<\/span>(img &amp;&amp; text)\n            <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'capacity'<\/span>).innerHTML=<span class=\"hljs-string\">'('<\/span>+textarea.value.length + <span class=\"hljs-string\">'\/'<\/span> + steg.getHidingCapacity(img) +<span class=\"hljs-string\">' chars)'<\/span>;\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The Image shows what the <code>handleFileSelect()<\/code> function achieves.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1653390149\/img.png\" alt=\"img.png\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1350\" height=\"626\"\/><\/p>\n<\/li>\n<\/ul>\n<h3>Writing the hide function to encode the text<\/h3>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">hide<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">var<\/span> stego = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"stego\"<\/span>),\n        img = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"img\"<\/span>),\n        cover = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"cover\"<\/span>),\n        message = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"message\"<\/span>),\n        textarea = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"text\"<\/span>),\n        download = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"download\"<\/span>);\n    <span class=\"hljs-keyword\">if<\/span>(img &amp;&amp; textarea) {\n        cover.src = steg.encode(textarea.value, img);\n        stego.className = <span class=\"hljs-string\">\"half\"<\/span>;\n        message.innerHTML=<span class=\"hljs-string\">\"\"<\/span>;\n        message.parentNode.className=<span class=\"hljs-string\">\"invisible\"<\/span>;\n        download.href=cover.src.replace(<span class=\"hljs-string\">\"image\/png\"<\/span>, <span class=\"hljs-string\">\"image\/octet-stream\"<\/span>);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ul>\n<li>\n<code>hide(){...}<\/code> This function also returns the elements with their specific values using the <code>document.getElementById<\/code>\n<\/li>\n<li>If both the <code>img<\/code> and <code>textarea<\/code> values are not <code>null<\/code> we are going to <strong>encode<\/strong> our text inside the uploaded image.\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">cover.src = steg.encode(textarea.value, img);\n<\/code><\/span><\/pre>\n<\/li>\n<\/ul>\n<blockquote>\n<p><code>steganography.js<\/code> provides an object called <code>steg<\/code> which we can invoke the <code>encode<\/code> method and having the text as <code>textarea.value<\/code> and image as <code>img<\/code> as arguments to the method.<\/p>\n<\/blockquote>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1653391074\/img1.png\" alt=\"img.png\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1352\" height=\"624\"\/>\nTo download the encoded image using HTML5 we can add the download attribute to our download button link<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"download\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-success\"<\/span> <span class=\"hljs-attr\">download<\/span>=<span class=\"hljs-string\">\"cover.png\"<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"nofollow\"<\/span>&gt;<\/span>Download<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We will also need to change the type of our image to an <strong><em>octet-stream<\/em><\/strong> so that when you download it with a missing extension or unknown format your system will recognize it as an octet-file(binary file).<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">download.href=cover.src.replace(<span class=\"hljs-string\">\"image\/png\"<\/span>, <span class=\"hljs-string\">\"image\/octet-stream\"<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Writing the read function to encode the text<\/h3>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">read<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">var<\/span> img = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"img\"<\/span>),\n        cover = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"cover\"<\/span>),\n        message = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"message\"<\/span>),\n        textarea = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"text\"<\/span>);\n    <span class=\"hljs-keyword\">if<\/span>(img &amp;&amp; textarea) {\n        message.innerHTML = steg.decode(img);\n        <span class=\"hljs-keyword\">if<\/span>(message.innerHTML !== <span class=\"hljs-string\">\"\"<\/span>) {\n            message.parentNode.className=<span class=\"hljs-string\">\"\"<\/span>;\n            textarea.value = message.innerHTML;\n            updateCapacity();\n        }\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ul>\n<li>\n<p><code>read()<\/code>This function also returns the elements with their specific values using the <code>document.getElementById<\/code> used in our read function.<\/p>\n<p>If the <code>textarea<\/code> and <code>img<\/code> field has values, <code>decode<\/code> the text inside the encoded image.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">message.innerHTML = steg.decode(img);\n<\/code><\/span><\/pre>\n<\/li>\n<\/ul>\n<blockquote>\n<p><code>decode<\/code> function by steganography.js decodes the encoded image and retrieves the text encoded in the image.<\/p>\n<\/blockquote>\n<p>If the message field has a value copy it to the textarea field and this time let\u2019s make the div <strong>visible<\/strong> unlike we did with the two functions above.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">if<\/span>(message.innerHTML !== <span class=\"hljs-string\">\"\"<\/span>) {\n   message.parentNode.className=<span class=\"hljs-string\">\"\"<\/span>;\n   textarea.value = message.innerHTML;\n   updateCapacity();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The image below shows the effect of the <code>read<\/code> function.\n<img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1653391226\/img2.png\" alt=\"img.png\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1335\" height=\"624\"\/><\/p>\n<h2>Deploying your application to vercel<\/h2>\n<p>When you have pushed your project to github, go to <a href=\"https:\/\/vercel.com\/signup?next=%2Fdashboard\">Vercel<\/a> and sign up with github. Go to the dashboard<img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1653391307\/img_3.png\" alt=\"img.png\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1349\" height=\"685\"\/> Click new project and import your github project. Click deploy to deploy your project on Vercel. <img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1653391442\/img_2.png\" alt=\"img_2.png\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1347\" height=\"630\"\/> Nice! we just deployed our application to vercel. Click <a href=\"https:\/\/steganography-with-js.vercel.app\/\">this link<\/a> to view the deployed project.<\/p>\n<h2>Conclusion<\/h2>\n<p>In conclusion, we saw how we could encode and decode text in images using steganography.js and JavaScript. We also learned how to deploy our application on Vercel<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28210,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,177,402,371],"class_list":["post-28209","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-javascript","tag-png","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Hiding Text in Images Using Plain JavaScript<\/title>\n<meta name=\"description\" content=\"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let&#039;s explore on how we can achieve this.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hiding Text in Images Using Plain JavaScript\" \/>\n<meta property=\"og:description\" content=\"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let&#039;s explore on how we can achieve this.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-24T11:42:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-16T18:19:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"259\" \/>\n\t<meta property=\"og:image:height\" content=\"194\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Hiding Text in Images Using Plain JavaScript\",\"datePublished\":\"2022-05-24T11:42:25+00:00\",\"dateModified\":\"2025-02-16T18:19:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Javascript\",\"PNG\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\",\"name\":\"Hiding Text in Images Using Plain JavaScript\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA\",\"datePublished\":\"2022-05-24T11:42:25+00:00\",\"dateModified\":\"2025-02-16T18:19:38+00:00\",\"description\":\"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let's explore on how we can achieve this.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA\",\"width\":259,\"height\":194},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hiding Text in Images Using Plain JavaScript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Hiding Text in Images Using Plain JavaScript","description":"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let's explore on how we can achieve this.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/","og_locale":"en_US","og_type":"article","og_title":"Hiding Text in Images Using Plain JavaScript","og_description":"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let's explore on how we can achieve this.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-05-24T11:42:25+00:00","article_modified_time":"2025-02-16T18:19:38+00:00","og_image":[{"width":259,"height":194,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/"},"author":{"name":"","@id":""},"headline":"Hiding Text in Images Using Plain JavaScript","datePublished":"2022-05-24T11:42:25+00:00","dateModified":"2025-02-16T18:19:38+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA","keywords":["Guest Post","Image","Javascript","PNG","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/","name":"Hiding Text in Images Using Plain JavaScript","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA","datePublished":"2022-05-24T11:42:25+00:00","dateModified":"2025-02-16T18:19:38+00:00","description":"Steganography is the process of concealing information in an image or any other digital artifact. Steganography is used to conceal text from unauthorized parties. With JavaScript we can easily use steganography.js to assist us in hiding\/encoding data inside images and decoding\/viewing the hidden message. Let's explore on how we can achieve this.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA","width":259,"height":194},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/hiding-text-in-images-using-plain-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Hiding Text in Images Using Plain JavaScript"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925111\/Web_Assets\/blog\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083\/8c359fc1e7187f4db6a0fe87a19558655a80f33b-259x194-1_28210a5083.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28209"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28209\/revisions"}],"predecessor-version":[{"id":36855,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28209\/revisions\/36855"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28210"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}