<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Stickers – IMG.LY Blog</title><description>Posts tagged Stickers on the IMG.LY blog.</description><link>https://img.ly/blog/tag/stickers/</link><language>en-us</language><image><url>https://img.ly/apple-touch-icon.png</url><title>Stickers – IMG.LY Blog</title><link>https://img.ly/blog/tag/stickers/</link></image><atom:link href="https://img.ly/blog/tag/stickers/rss.xml" rel="self" type="application/rss+xml"/><generator>Astro</generator><lastBuildDate>Wed, 24 Jun 2026 09:29:44 GMT</lastBuildDate><ttl>60</ttl><item><title>How To Add a Sticker to a Texture With Three.js</title><link>https://img.ly/blog/how-to-add-a-sticker-to-a-texture-with-three-js/</link><guid isPermaLink="true">https://img.ly/blog/how-to-add-a-sticker-to-a-texture-with-three-js/</guid><description>Learn how to add an overlay image to your textures in WebGL and JavaScript with Three.js.</description><pubDate>Fri, 25 Feb 2022 15:10:58 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Disclaimer: This article has been updated in June 2023 to reflect the changes introduced by &lt;a href=&quot;https://github.com/mrdoob/three.js/wiki/Migration-Guide#149--150&quot;&gt;Three.js r150&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this article, you will learn to add a sticker to a texture with &lt;a href=&quot;https://get.webgl.org/&quot;&gt;WebGL&lt;/a&gt;. In detail, you will see how to use the &lt;a href=&quot;https://threejs.org/&quot;&gt;Three.js&lt;/a&gt; JavaScript library to add an overlay image to a texture. Check out our guide to explore other image editing operations, such as &lt;a href=&quot;https://img.ly/blog/how-to-resize-an-image-in-react/&quot;&gt;resizing an image in React&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dealing with 3D graphics used to be a challenging, complex, and time-consuming task. Thanks to libraries like &lt;code&gt;three.js&lt;/code&gt;, it has become more accessible than ever. Follow this easy step-by-step how-to and achieve the following result:&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Here are all the prerequisites you need to meet to follow this tutorial and build the demo application shown above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nodejs.org/en&quot;&gt;Node.js &gt;= 18&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mrdoob/three.js&quot;&gt;Three.js &gt;= r150&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Explore the official documentation page to learn about &lt;a href=&quot;https://threejs.org/docs/#manual/en/introduction/Installation&quot;&gt;how to install &lt;code&gt;three.js&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-is-threejs&quot;&gt;What is Three.js?&lt;/h2&gt;
&lt;p&gt;As stated in the &lt;a href=&quot;https://github.com/mrdoob/three.js/&quot;&gt;GitHub page of the project&lt;/a&gt;, the goal of the Three.js project is to create a lightweight 3D JavaScript library with a very low level of complexity. In other words, Three.js aims to make 3D graphics more accessible, especially considering that Three.js only requires a browser to run.&lt;/p&gt;
&lt;p&gt;To be more specific, it allows you to create a 3D graphics project where you can modify elements in your browser and see visual feedback. The library is currently built on top of a &lt;a href=&quot;https://threejs.org/docs/#api/en/renderers/WebGLRenderer&quot;&gt;WebGL renderer&lt;/a&gt;, but it also supports &lt;a href=&quot;https://en.wikipedia.org/wiki/WebGPU&quot;&gt;WebGPU&lt;/a&gt;, &lt;a href=&quot;https://threejs.org/docs/#examples/en/renderers/SVGRenderer&quot;&gt;SVG&lt;/a&gt;, and &lt;a href=&quot;https://threejs.org/docs/#examples/en/renderers/CSS3DRenderer&quot;&gt;CSS3D&lt;/a&gt; renderers.&lt;/p&gt;
&lt;p&gt;If you are not familiar with these concepts, &lt;a href=&quot;https://en.wikipedia.org/wiki/WebGL&quot;&gt;WebGL&lt;/a&gt; stands for “Web Graphics Library” and is a JavaScript API for rendering high-performance interactive 3D and 2D graphics. You can use it in many web browsers without external plugins or libraries.&lt;/p&gt;
&lt;p&gt;As you can verify from the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API#browser_compatibility&quot;&gt;MDN compatibility page&lt;/a&gt;, browsers currently support the most popular WebGL features. However, keep in mind that the user’s device must meet hardware requirements for some features to work.&lt;/p&gt;
&lt;p&gt;WebGL is undoubtedly a powerful tool but requires a lot of skill and involves a lot of boilerplate code. Here is where Three.js comes into play, making 3D development much easier.&lt;/p&gt;
&lt;p&gt;Now, let’s see it in action!&lt;/p&gt;
&lt;h2 id=&quot;adding-an-overlay-image-to-a-texture-in-webgl&quot;&gt;Adding an Overlay Image to a Texture in WebGL&lt;/h2&gt;
&lt;p&gt;Clone the &lt;a href=&quot;https://github.com/Tonel/how-to-add-a-sticker-with-threejs-imgly&quot;&gt;GitHub repository that supports this article&lt;/a&gt; with the following commands:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; clone&lt;/span&gt;&lt;span&gt; https://github.com/Tonel/how-to-add-a-sticker-with-threejs-imgly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Additionally, try the demo application by launchingthe command below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, visit &lt;code&gt;http://localhost:5000&lt;/code&gt; in the browser.&lt;/p&gt;
&lt;p&gt;Now that you know what the demo app looks like, keep following this tutorial and learn how to build it.&lt;/p&gt;
&lt;p&gt;Specifically, this is the entire JavaScript code required to achieve the goal:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; as&lt;/span&gt;&lt;span&gt; THREE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;three&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { OrbitControls } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &apos;three/addons/controls/OrbitControls.js&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// set up the scene, camera, and renderer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; scene&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Scene&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; camera&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;PerspectiveCamera&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  40&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  window.innerWidth &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; window.innerHeight,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;camera.position.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;150&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;150&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; OrbitControls&lt;/span&gt;&lt;span&gt;(camera, document.body);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// initialize the WebGL renderer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; renderer&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;WebGLRenderer&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;renderer.&lt;/span&gt;&lt;span&gt;setSize&lt;/span&gt;&lt;span&gt;(window.innerWidth, window.innerHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;document.body.&lt;/span&gt;&lt;span&gt;appendChild&lt;/span&gt;&lt;span&gt;(renderer.domElement);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// add light to the scene to make the texture visible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; light&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AmbientLight&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0xffffff&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;scene.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(light);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// add the axes helper indicator to the scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;scene.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AxesHelper&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// load the base texture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; texture&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TextureLoader&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;https://threejs.org/examples/textures/hardwood2_diffuse.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a new buffer geometry and place it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// to the horizontal plane&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; textureGeometry&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;PlaneGeometry&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;textureGeometry.&lt;/span&gt;&lt;span&gt;rotateX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;90&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.MathUtils.&lt;/span&gt;&lt;span&gt;DEG2RAD&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// translate the plane to the center of the scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;textureGeometry.&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;25&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;25&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a MeshBasicMaterial with the base texture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; textureMaterial&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MeshBasicMaterial&lt;/span&gt;&lt;span&gt;({ map: texture });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a mesh using the geometry and material&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// and add it to the scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; textureMesh&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Mesh&lt;/span&gt;&lt;span&gt;(textureGeometry, textureMaterial);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;scene.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(textureMesh);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// repeat the same logic to place the sticker image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// over the texture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; sticker&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TextureLoader&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &apos;https://i.imgur.com/IYh17Rv.png&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; stickerGeometry&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;PlaneGeometry&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;stickerGeometry.&lt;/span&gt;&lt;span&gt;rotateX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;90&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.MathUtils.&lt;/span&gt;&lt;span&gt;DEG2RAD&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;stickerGeometry.&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;25&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;25&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; stickerMaterial&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MeshBasicMaterial&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  map: sticker,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  transparent: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// create a mesh using the image geometry and material&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; imageMesh&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; THREE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Mesh&lt;/span&gt;&lt;span&gt;(stickerGeometry, stickerMaterial);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;scene.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(imageMesh);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// adjust the position and rotation of the sticker mesh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// by setting the y-coordinate to 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// in order for the sticker to rest on the texture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;imageMesh.position.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// render the scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; launchThreeJs&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  requestAnimationFrame&lt;/span&gt;&lt;span&gt;(launchThreeJs);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  renderer.&lt;/span&gt;&lt;span&gt;render&lt;/span&gt;&lt;span&gt;(scene, camera);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;launchThreeJs&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, the code imports the necessary components from the Three.js library. Next, it initialize a &lt;a href=&quot;https://threejs.org/docs/#api/en/scenes/Scene&quot;&gt;&lt;code&gt;Scene&lt;/code&gt;&lt;/a&gt; and set up a &lt;a href=&quot;https://threejs.org/docs/#api/en/cameras/PerspectiveCamera&quot;&gt;&lt;code&gt;PerspectiveCamera&lt;/code&gt;&lt;/a&gt; with &lt;a href=&quot;https://threejs.org/docs/#examples/en/controls/OrbitControls&quot;&gt;&lt;code&gt;OrbitsControl&lt;/code&gt;&lt;/a&gt;, allowing the user to move around. Then, it creates a WebGL renderer and sets its size to match the window’s dimensions. The scene is lit by an &lt;a href=&quot;https://threejs.org/docs/#api/en/lights/AmbientLight&quot;&gt;&lt;code&gt;AmbientLight&lt;/code&gt;&lt;/a&gt; instance, which illuminates all objects in the scene equally.&lt;/p&gt;
&lt;p&gt;The snippet loads a base texture using TextureLoader from the given URL, creates a &lt;a href=&quot;https://threejs.org/docs/#api/en/geometries/PlaneGeometry&quot;&gt;&lt;code&gt;PlaneGeometry&lt;/code&gt;&lt;/a&gt;, defines a mesh with some geometries, and then add the resulting element to the scene. This logic will take care of rendering the texture image in the scene.&lt;/p&gt;
&lt;p&gt;To add the sticker to the texture, the same procude gets repeated. This time, Three.js is instructed to load a sticker image and position it over the original texture. Note that the position of the sticker mesh is adjusted by setting its y-coordinate to 1 to ensure the new image rests on top of the old one.&lt;/p&gt;
&lt;p&gt;Et voilà! You just learned how to add a sticker to a WebGL texture with &lt;code&gt;three.js&lt;/code&gt;!&lt;/p&gt;
&lt;h2 id=&quot;adding-a-sticker-with-photoeditorsdk&quot;&gt;Adding a Sticker With &lt;a href=&quot;https://www.npmjs.com/package/photoeditorsdk&quot;&gt;&lt;code&gt;PHOTOEDITORSDK&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://img.ly/docs/pesdk/web/introduction/migration-guide/#canvas-renderer/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=howtos&quot;&gt;PhotoEditorSDK uses WebGL as the main renderer&lt;/a&gt;. You can effortlessly add a sticker to your textures without writing any line of code. WebGL will be used behind the scene. Consequently, you do not need to know WebGL or code in GLSL to harness its power.&lt;/p&gt;
&lt;p&gt;Adding a sticker to an image only takes a few seconds here. Just jump to &lt;a href=&quot;https://img.ly/docs/pesdk/web/guides/umd/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=howtos&quot;&gt;this article&lt;/a&gt; from the official documentation and learn how to get started with PhotoEditorSDK in Vanilla JavaScript. Then, upload your texture image and a sticker with the &lt;a href=&quot;https://img.ly/docs/pesdk/web/features/stickers/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=howtos&quot;&gt;Sticker feature&lt;/a&gt;. As shown below, you can position a sticker on top of the original image with a point-and-click UI:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;how-add-sticker-to-texture-image-three-js-webgl&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 700px) 700px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;700&quot; height=&quot;376&quot; src=&quot;https://img.ly/_astro/how-add-sticker-to-texture-image-three-js-webgl_1IEwVR.webp&quot; srcset=&quot;/_astro/how-add-sticker-to-texture-image-three-js-webgl_29mIIu.webp 640w, /_astro/how-add-sticker-to-texture-image-three-js-webgl_1IEwVR.webp 700w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Check out this feature on the &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditorSDK demo page&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Today we learned how to add an overlay image to a WebGL texture in JavaScript with &lt;code&gt;three.js&lt;/code&gt;. This tool makes it easier to deal with WebGL and 3D graphics. In particular, by using one of the many plugins supporting the Three.js project, we were able to add a sticker to a texture with just a bunch of lines of code.&lt;/p&gt;
&lt;p&gt;3D graphics remains a complex topic, especially when it comes to developing in the OpenGL Shading Language. Three.js tries to hide this encumbrance as much as possible, but sometimes you still require it. If you want to avoid using WebGL directly to achieve your goal, consider an all-in-one and easy-to-use solution – such as &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditorSDK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks for reading! We hope that you found this article helpful. Feel free to reach out to us on &lt;a href=&quot;https://twitter.com/imgly&quot;&gt;Twitter&lt;/a&gt; with any questions, comments, or suggestions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To stay in the loop with our latest articles and case studies, subscribe to our &lt;a href=&quot;https://img.us13.list-manage.com/subscribe?u=dc9f652839dbb620d14d6d28d&amp;#x26;id=04a306e4b2&quot;&gt;Newsletter&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Antonello</dc:creator><media:content url="https://blog.img.ly/2022/02/add-sticker-to-image-texture-three-js-threejs.png" medium="image"/><category>How-To</category><category>Image Editing</category><category>Image Processing</category><category>3D</category><category>Photo Editing</category><category>Stickers</category><category>Tech</category><category>Tutorial</category></item><item><title>How to Add a Watermark to an Image in JavaScript</title><link>https://img.ly/blog/how-to-add-watermark-javascript/</link><guid isPermaLink="true">https://img.ly/blog/how-to-add-watermark-javascript/</guid><description>Create watermarks in Vanilla JavaScript and with watermarkjs!</description><pubDate>Tue, 07 Dec 2021 15:54:32 GMT</pubDate><content:encoded>&lt;p&gt;In this tutorial, you will learn how to watermark an image in both Vanilla JavaScript and with &lt;a href=&quot;https://www.npmjs.com/package/watermarkjs&quot;&gt;&lt;code&gt;watermarkjs&lt;/code&gt;&lt;/a&gt;. The first approach is primarily based on the HTML5 &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API&quot;&gt;&lt;code&gt;&amp;#x3C;canvas&gt;&lt;/code&gt;&lt;/a&gt; element which can be used for applying filters or &lt;a href=&quot;https://img.ly/blog/how-to-compress-an-image-before-uploading-it-in-javascript/&quot;&gt;resizing an image&lt;/a&gt;, while the second one involves a popular npm library.&lt;/p&gt;
&lt;p&gt;A watermark is a marker deliberately embedded in an audio, video, or image data source, generally used to claim ownership of that source. In the case of an image, a watermark can be represented by text or another image. So, image watermarking is the process of placing an overlay image or text on top of the original image, usually in one of the corners.&lt;/p&gt;
&lt;p&gt;Now, let’s see two methods to watermark an image in JavaScript. Follow this step-by-step tutorial and learn how to implement this demo:&lt;/p&gt;
&lt;h2 id=&quot;watermarking-images-in-javascript&quot;&gt;Watermarking Images in JavaScript&lt;/h2&gt;
&lt;p&gt;Keep following this step-by-step tutorial to learn how to watermarker an image in JavaScript. Otherwise, clone the following &lt;a href=&quot;https://github.com/Tonel/how-to-watermark-an-image-img-ly&quot;&gt;GitHub repository supporting the article&lt;/a&gt; by launching this command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;git clone https://github.com/Tonel/how-to-watermark-an-image-img-ly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, open the &lt;code&gt;index.html&lt;/code&gt; file in your browser to give a look at the real-world demo you are about to see how to build.&lt;/p&gt;
&lt;h3 id=&quot;1a-implementing-the-watermarking-logic-using-html5-canvas&quot;&gt;1.A Implementing the watermarking logic using HTML5 &lt;code&gt;&amp;#x3C;canvas&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;With this approach, you can achieve the watermarking goal by employing solely the HTML5 &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API&quot;&gt;&lt;code&gt;&amp;#x3C;canvas&gt;&lt;/code&gt;&lt;/a&gt; element. In other words, there are no prerequisites.&lt;/p&gt;
&lt;p&gt;Let’s see in detail how to use a watermark image and a watermark text to an image in JavaScript:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; watermarkImage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImage&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkImagePath&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvas&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; context&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;getContext&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;2d&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasWidth&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.width;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasHeight&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.height;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.width &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasWidth;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.height &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasHeight;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // initializing the canvas with the original image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;drawImage&lt;/span&gt;&lt;span&gt;(originalImage, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // loading the watermark image and transforming it into a pattern&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; fetch&lt;/span&gt;&lt;span&gt;(watermarkImagePath);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; blob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; result.&lt;/span&gt;&lt;span&gt;blob&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; image&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; createImageBitmap&lt;/span&gt;&lt;span&gt;(blob);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; pattern&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; context.&lt;/span&gt;&lt;span&gt;createPattern&lt;/span&gt;&lt;span&gt;(image, &lt;/span&gt;&lt;span&gt;&apos;no-repeat&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // translating the watermark image to the bottom right corner&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;(canvasWidth &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; image.width, canvasHeight &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; image.height);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;rect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.fillStyle &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; pattern;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;toDataURL&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; watermarkImageWithText&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImage&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkText&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvas&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; context&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;getContext&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;2d&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasWidth&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.width;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasHeight&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.height;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.width &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasWidth;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.height &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasHeight;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // initializing the canvas with the original image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;drawImage&lt;/span&gt;&lt;span&gt;(originalImage, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // adding a blue watermark text in the bottom right corner&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.fillStyle &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;blue&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.textBaseline &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;middle&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.font &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;bold 25px serif&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;fillText&lt;/span&gt;&lt;span&gt;(watermarkText, canvasWidth &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt;, canvasHeight &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;toDataURL&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In both cases, an in-memory HTML &lt;code&gt;&amp;#x3C;canvas&gt;&lt;/code&gt; with a 2D rendering context having the same size as the original image is created. Then, it is filled by drawing the original image inside it. From that point, the two functions follow different approaches to achieve the watermarking goal.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;watermarkImage()&lt;/code&gt; function, the watermark image path passed as a parameter is used to load the image file. Then, it is transformed into an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap&quot;&gt;&lt;code&gt;ImageBitmap&lt;/code&gt;&lt;/a&gt; object by using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/createImageBitmap&quot;&gt;&lt;code&gt;createImageBitmap()&lt;/code&gt;&lt;/a&gt; function. This is necessary because the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern&quot;&gt;&lt;code&gt;createPattern()&lt;/code&gt;&lt;/a&gt; function requires such a data structure to create a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern&quot;&gt;&lt;code&gt;CanvasPattern&lt;/code&gt;&lt;/a&gt; object that can be used to draw a particular image over a non-empty canvas. In particular, the drawing operation involves a rectangle containing the pattern created with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rect&quot;&gt;&lt;code&gt;rect()&lt;/code&gt;&lt;/a&gt; function. This is first translated to the required position and finally drawn with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill&quot;&gt;&lt;code&gt;fill()&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;watermarkImageWithText()&lt;/code&gt; function is simpler. This is because the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D&quot;&gt;&lt;code&gt;CanvasRenderingContext2D&lt;/code&gt;&lt;/a&gt; natively comes with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillText&quot;&gt;&lt;code&gt;fillText()&lt;/code&gt;&lt;/a&gt; function, which allows you to add text to an image with no effort.&lt;/p&gt;
&lt;p&gt;If you want to learn more on how to style the watermark image or text, reading &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle&quot;&gt;this&lt;/a&gt; page from &lt;a href=&quot;https://developer.mozilla.org/en-US/&quot;&gt;MDN Web Docs&lt;/a&gt; is recommended.&lt;/p&gt;
&lt;h3 id=&quot;1b-implementing-the-watermarking-logic-using-watermarkjs&quot;&gt;1.B Implementing the watermarking logic using &lt;code&gt;watermarkjs&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The same result can be achieved by using the &lt;a href=&quot;https://www.npmjs.com/package/watermarkjs&quot;&gt;&lt;code&gt;watermarkjs&lt;/code&gt;&lt;/a&gt; library with just a bunch of lines of code. In this case, you have to add it as a dependency to your project and you can learn how to do it &lt;a href=&quot;https://www.npmjs.com/package/watermarkjs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The two aforementioned function can now be implemented as follows:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; watermarkImage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImageFile&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkImagePath&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;destinationImage&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  watermark&lt;/span&gt;&lt;span&gt;([originalImageFile, watermarkImagePath])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;(watermark.image.&lt;/span&gt;&lt;span&gt;lowerRight&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;watermarkedImage&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      destinationImage &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; watermarkedImage.src;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; watermarkImageWithText&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImageFile&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkText&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;destinationImage&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  watermark&lt;/span&gt;&lt;span&gt;([originalImageFile, watermarkImagePath])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;(watermark.text.&lt;/span&gt;&lt;span&gt;lowerRight&lt;/span&gt;&lt;span&gt;(watermarkText, &lt;/span&gt;&lt;span&gt;&quot;bold 25px serif&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;#0000ff&quot;&lt;/span&gt;&lt;span&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;watermarkedImage&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      destinationImage &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; watermarkedImage.src;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main difference from the first method is that the &lt;code&gt;watermark&lt;/code&gt; object coming with the library accepts either a URL path to the image or its &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/File&quot;&gt;&lt;code&gt;File&lt;/code&gt;&lt;/a&gt; object. Then, it requires the destination image to write the generated watermarked image.&lt;/p&gt;
&lt;p&gt;You can find more demos on the library’s &lt;a href=&quot;https://github.com/brianium/watermarkjs&quot;&gt;GitHub page&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;2-watermarking-in-action&quot;&gt;2. Watermarking in action&lt;/h3&gt;
&lt;p&gt;Let’s now see how to employ the &lt;code&gt;watermarkImage()&lt;/code&gt; and &lt;code&gt;watermarkImageWithText()&lt;/code&gt; functions to build a real-word example.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;!&lt;/span&gt;&lt;span&gt;DOCTYPE&lt;/span&gt;&lt;span&gt; html&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&gt;Image Watermarker&amp;#x3C;/&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;&gt;Please, upload an image and a watermark will be added&amp;#x3C;/&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;upload&quot;&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;file&quot;&lt;/span&gt;&lt;span&gt; accept&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;image/*&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;images&quot;&lt;/span&gt;&lt;span&gt; style&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;visibility: hidden;&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;Original image&amp;#x3C;/&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;img&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;originalImage&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;Watermarked image 1 (image watermark)&amp;#x3C;/&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;img&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;watermarkedImage&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;Watermarked image 2 (text watermark)&amp;#x3C;/&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;&lt;/span&gt;&lt;span&gt;img&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;watermarkedImageWithText&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x3C;&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;src/index.js&quot;&lt;/span&gt;&lt;span&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;script&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// hiding the div that will contain the images&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; imagesDiv&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;querySelector&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;#images&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; fileInput&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;querySelector&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;#upload&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fileInput.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;change&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;file&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; fileInput.files;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // displaying the uploaded image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; originalImage&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;querySelector&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;#originalImage&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  originalImage.src &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; fileToDataUri&lt;/span&gt;&lt;span&gt;(file);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // adding the image watermark to the original image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // and showing the watermarked image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; watermarkedImage&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;querySelector&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;#watermarkedImage&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; watermarkedImageWithText&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;querySelector&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &apos;#watermarkedImageWithText&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  originalImage.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;load&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    watermarkedImage.src &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; watermarkImage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      originalImage,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &apos;./src/IMG.LY.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    watermarkedImageWithText.src &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; watermarkImageWithText&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      originalImage,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &apos;IMG.LY&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // making the div containing the image visible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  imagesDiv.style.visibility &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;visible&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; fileToDataUri&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    const&lt;/span&gt;&lt;span&gt; reader&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; FileReader&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    reader.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;load&apos;&lt;/span&gt;&lt;span&gt;, () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      resolve&lt;/span&gt;&lt;span&gt;(reader.result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    reader.&lt;/span&gt;&lt;span&gt;readAsDataURL&lt;/span&gt;&lt;span&gt;(field);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; watermarkImage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImage&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkImagePath&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvas&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; context&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;getContext&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;2d&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasWidth&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.width;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasHeight&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.height;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.width &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasWidth;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.height &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasHeight;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // initializing the canvas with the original image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;drawImage&lt;/span&gt;&lt;span&gt;(originalImage, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // loading the watermark image and transforming it into a pattern&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; fetch&lt;/span&gt;&lt;span&gt;(watermarkImagePath);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; blob&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; result.&lt;/span&gt;&lt;span&gt;blob&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; image&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; createImageBitmap&lt;/span&gt;&lt;span&gt;(blob);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; pattern&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; context.&lt;/span&gt;&lt;span&gt;createPattern&lt;/span&gt;&lt;span&gt;(image, &lt;/span&gt;&lt;span&gt;&apos;no-repeat&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // translating the watermark image to the bottom right corner&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;(canvasWidth &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; image.width, canvasHeight &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; image.height);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;rect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.fillStyle &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; pattern;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;toDataURL&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; watermarkImageWithText&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;originalImage&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;watermarkText&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvas&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; document.&lt;/span&gt;&lt;span&gt;createElement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; context&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;getContext&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;2d&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasWidth&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.width;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; canvasHeight&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; originalImage.height;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.width &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasWidth;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  canvas.height &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; canvasHeight;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // initializing the canvas with the original image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;drawImage&lt;/span&gt;&lt;span&gt;(originalImage, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, canvasWidth, canvasHeight);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  // adding a blue watermark text in the bottom right corner&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.fillStyle &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;blue&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.textBaseline &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;middle&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.font &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;bold 25px serif&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  context.&lt;/span&gt;&lt;span&gt;fillText&lt;/span&gt;&lt;span&gt;(watermarkText, canvasWidth &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt;, canvasHeight &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; canvas.&lt;/span&gt;&lt;span&gt;toDataURL&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second snipper represents the &lt;code&gt;src/index.js&lt;/code&gt; file and this is where the complete logic is implemented. First, users can upload an image thanks to the &lt;code&gt;&amp;#x3C;input&gt;&lt;/code&gt; tag. Then, the two aforementioned functions are used to produce two watermarked images that are finally shown on the page. To make this application works, note that the &lt;code&gt;&quot;./src/IMG.LY.jpg&quot;&lt;/code&gt; path should be replaced with the relative path to your watermark image.&lt;/p&gt;
&lt;h2 id=&quot;final-considerations&quot;&gt;Final Considerations&lt;/h2&gt;
&lt;p&gt;Although watermarking does not involve complex logic, it does present some challenges. In fact, the approaches presented above cannot but be considered basic. This is because to properly implement watermarking, you should allow users to choose where precisely to place the watermark, with what style and colors, and with the desired size. Otherwise, the final result may be inaccurate and completely alter the original image.&lt;/p&gt;
&lt;p&gt;In other words, giving users the ability to add a watermark to an image requires an advanced UI. Building it may be complex, time-consuming, and represent a waste of energy. Especially considering how such a feature may be marginal in your application. This is why you should take into consideration an advanced SDK solution, such as &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditorSDK&lt;/a&gt;. This allows you to provide users with watermarking, and many other cool features.&lt;/p&gt;
&lt;h2 id=&quot;adding-a-watermark-to-an-image-with-photoeditorsdk&quot;&gt;Adding a Watermark to an Image With &lt;a href=&quot;https://www.npmjs.com/package/photoeditorsdk&quot;&gt;&lt;code&gt;photoeditorsdk&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, read &lt;a href=&quot;https://img.ly/docs/pesdk/web/guides/umd/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=howtos&quot;&gt;this article&lt;/a&gt; from the official documentation on how to get started with PhotoEditorSDK in Vanilla JavaScript. By uploading an image with the &lt;a href=&quot;https://img.ly/docs/pesdk/web/features/stickers/?utm_source=imgly&amp;#x26;utm_medium=blog&amp;#x26;utm_campaign=howtos&quot;&gt;Sticker feature&lt;/a&gt;, you can place another image on top of the original one whenever you want. This allows you to achieve a watermark effect with no effort.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;add-watermark-sticker-javascript&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1206px) 1206px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1206&quot; height=&quot;647&quot; src=&quot;https://img.ly/_astro/add-watermark-sticker-javascript_Z1SEjng.webp&quot; srcset=&quot;/_astro/add-watermark-sticker-javascript_ZsYh8o.webp 640w, /_astro/add-watermark-sticker-javascript_Z45T6H.webp 750w, /_astro/add-watermark-sticker-javascript_Z2lloyt.webp 828w, /_astro/add-watermark-sticker-javascript_1cCj3Q.webp 1080w, /_astro/add-watermark-sticker-javascript_Z1SEjng.webp 1206w&quot;&gt;&lt;br&gt;
Check out this feature in the &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, we learned how to watermark an image in both Vanilla JavaScript and &lt;code&gt;watermarkjs&lt;/code&gt;. The first approach involved the HTML5 &lt;code&gt;&amp;#x3C;canvas&gt;&lt;/code&gt;, which makes adding a watermark to an image easy. The second is even more straightforward and requires just a few lines of code. In both cases, the task is almost effortless. On the other hand, implementing a watermark feature that allows users to deal with the watermark image with freedom requires an entire UI. Building it takes time and effort, and may do not want to waste time on it. In this case, you should adopt a more complete, advanced, and ready-to-use solution – such as &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditorSDK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks for reading! We hope that you found this article helpful. Feel free to reach out to us on &lt;a href=&quot;https://twitter.com/imgly&quot;&gt;Twitter&lt;/a&gt; with any questions, comments, or suggestions.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Antonello</dc:creator><media:content url="https://blog.img.ly/2021/12/watermark-sticker-javascript-1.png" medium="image"/><category>How-To</category><category>JavaScript</category><category>Photo Editing</category><category>Stickers</category><category>App Development</category><category>Web Development</category><category>Tutorial</category></item><item><title>Flutter: Our new plugins made for Dart developers</title><link>https://img.ly/blog/flutter-native-plugins-made-for-dart-developers/</link><guid isPermaLink="true">https://img.ly/blog/flutter-native-plugins-made-for-dart-developers/</guid><description>We are happy to announce our new official Flutter plugins wrapping our native PhotoEditor SDK and VideoEditor SDK for one of the most popular cross-platform frameworks.</description><pubDate>Thu, 11 Mar 2021 14:12:09 GMT</pubDate><content:encoded>&lt;p&gt;Flutter enables developers to build native iOS and Android applications with a single Dart codebase whilst the application’s performance is kept at a very high native-like level. This is even more ensured by the huge amount of Flutter plugins, which wrap native code for the use in Dart.&lt;/p&gt;
&lt;p&gt;With the rising demand for photo and video editing solutions, we were committed to provide plugins that enable developers to use our &lt;a href=&quot;https://img.ly/docs/pesdk/&quot;&gt;native PhotoEditor SDK&lt;/a&gt; and our &lt;a href=&quot;https://img.ly/docs/vesdk/&quot;&gt;native VideoEditor SDK&lt;/a&gt; within their Flutter applications. This said we are proud to announce that the Flutter plugins &lt;a href=&quot;https://pub.dev/packages/photo_editor_sdk&quot;&gt;&lt;code&gt;photo_editor_sdk&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://pub.dev/packages/video_editor_sdk&quot;&gt;&lt;code&gt;video_editor_sdk&lt;/code&gt;&lt;/a&gt; are now extending our list of cross-platform modules. The combination of both products allows you to add comprehensive image and video editing tools to your Flutter application for iOS and Android - within minutes.&lt;/p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;p&gt;While building the plugins, we focused on making the use and integration of our existing SDKs as easy as possible and minimizing the required platform-specific knowledge and skillset. Therefore, using the plugins is as easy as writing a single line of Dart code:&lt;/p&gt;

&lt;h3 id=&quot;customization&quot;&gt;Customization&lt;/h3&gt;
&lt;p&gt;Furthermore, we wanted to keep the high level of customization options like cropping or resizing that our customers are used to in our products. In this sense, we created a dedicated &lt;a href=&quot;https://pub.dev/documentation/imgly_sdk/latest/imgly_sdk/Configuration-class.html&quot;&gt;&lt;code&gt;Configuration&lt;/code&gt;&lt;/a&gt; Dart class which serves the option to customize the SDK to your needs without ever leaving the Flutter world.&lt;br&gt;
Using the configuration is fast and easy:&lt;/p&gt;

&lt;h2 id=&quot;where-to-go-from-here&quot;&gt;Where to go from here?&lt;/h2&gt;
&lt;p&gt;Feel free to explore our packages, usage examples as well as the API documentation on &lt;a href=&quot;https://pub.dev/publishers/img.ly/packages&quot;&gt;pub.dev&lt;/a&gt; and/ or &lt;a href=&quot;https://github.com/imgly?q=flutter&quot;&gt;GitHub&lt;/a&gt;.&lt;br&gt;
We released our new Flutter plugins under open-source licenses, so feedback and pull requests are welcome.&lt;/p&gt;</content:encoded><dc:creator>Leon</dc:creator><media:content url="https://blog.img.ly/2021/03/flutter-plugin-for-photo-video-editor-dart.jpg" medium="image"/><category>Flutter</category><category>Photo Editor</category><category>Developer</category><category>Video Editor</category><category>Android</category><category>iOS</category><category>Stickers</category><category>Tech</category><category>How-To</category><category>Company</category></item><item><title>Make it pop - introducing Animated and Smart Stickers</title><link>https://img.ly/blog/smart-animated-stickers/</link><guid isPermaLink="true">https://img.ly/blog/smart-animated-stickers/</guid><description>Stickers have become an essential part of digital expression and a popular feature across use cases, from marketing campaigns and social media posts to annotation. We are happy to announce our newest feature.</description><pubDate>Thu, 13 Aug 2020 18:31:18 GMT</pubDate><content:encoded>&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Our latest release: brand-new sticker types for iOS and Android&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We are always on the lookout to improve our editor tools to engage users to be creative and add beautifully designed content.&lt;/p&gt;
&lt;p&gt;Our latest release for both mobile PhotoEditor SDK and VideoEditor SDK takes our stickers to the next level: With animated and smart stickers, we added popular features best known from apps like Instagram and TikTok – making editing more dynamic, expressive, and engaging. You can now capture your favorite moments by adding more context to your photos and videos. Maybe you finally landed that kickflip on a warm Monday morning, so you add the date and weather information. You can now also add your animated logo.  &lt;/p&gt;
&lt;p&gt;Our animated stickers not only provide you with a set of premade assets that come with the latest version of the editor but also let you integrate your custom ones tailored to your company and brand.&lt;/p&gt;
&lt;p&gt;Smart Stickers on the other hand open up a whole range of new possibilities, visualizing dynamic information like weather data, location, or dates. Like our text design feature, it’s the ease of use that makes these stickers special – simply cycle through different variations with a tap.&lt;/p&gt;
&lt;p&gt;Take a look at all updates and assets on our Mobile SDK page.    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://photoeditorsdk.com/mobile-sdk/?utm_campaign=Projects&amp;#x26;utm_medium=Blog&amp;#x26;utm_source=Main%20Blog&amp;#x26;utm_content=Sticker%20Types&quot;&gt;&lt;img alt=&quot;Check it out!&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 150px) 150px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;150&quot; height=&quot;47&quot; src=&quot;https://img.ly/_astro/check_it_out_Z21PgLn.webp&quot; srcset=&quot;/_astro/check_it_out_Z21PgLn.webp 150w&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS: Do you have feedback or suggestions for new smart stickers you want to see from us? Let us know in our &lt;a href=&quot;https://sales20200811.typeform.com/to/sP6dhXMc&quot;&gt;Quick-Survey&lt;/a&gt;. We’re happy to hear from you!&lt;/p&gt;</content:encoded><dc:creator>Michael K.</dc:creator><media:content url="https://blog.img.ly/2020/08/6mb-smartsticker-animatedsticker-pesdk.gif" medium="image"/><category>iOS</category><category>Android</category><category>Video Editing</category><category>Photo Editing</category><category>SDK</category><category>Colors</category><category>Stickers</category><category>Company</category></item></channel></rss>