<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="265949" data-post-id="265949">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a href="https://hex.pm/packages/image/0.13.0" rel="nofollow">Image version 0.13.0</a> has been released.  Lots of community encouragement and some fun challenges from <a class="mention" href="/u/genericjam" rel="nofollow">@GenericJam</a> that motivated the addition of chroma keying and meme generation.</p>
<h3><a name="p-265949-meme-generation-1" class="anchor" href="#p-265949-meme-generation-1" aria-label="Heading link" rel="nofollow"></a>Meme Generation</h3>
<p>Generates a meme image from a base image and some text. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; Image.open!("./test/support/images/meme.jpg", access: :random) 
..|&gt; Image.meme!("One simply cannot", text: "Enjoy image processing without libvips") 
..|&gt; Image.preview()
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/7/8/7846ffcf8cbda40540027de0f29201081ade4cbf.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/7846ffcf8cbda40540027de0f29201081ade4cbf" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/7/8/7846ffcf8cbda40540027de0f29201081ade4cbf.jpeg" alt="image" data-base62-sha1="ha1pws6GlSprg9QRffmaehfjShh" width="276" height="165"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">552×330 22.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<h3><a name="p-265949-chroma-keying-2" class="anchor" href="#p-265949-chroma-keying-2" aria-label="Heading link" rel="nofollow"></a>Chroma Keying</h3>
<p>This is the process of eliminating a background color or color range from an image to produce an image mask that can be overlayed onto another image. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; foreground =  Image.open!("./test/support/images/chroma_key/greenscreen.jpg", access: :random)
...&gt; |&gt; Image.preview()
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/3/0/30d2139ba9b8fa1d9a1968b26be2220f22d61fda.png" data-download-href="https://forum.elixirforum.com/uploads/default/30d2139ba9b8fa1d9a1968b26be2220f22d61fda" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/3/0/30d2139ba9b8fa1d9a1968b26be2220f22d61fda.png" alt="image" data-base62-sha1="6XT0lyDe1emF1gXgNEyMaeyoClc" width="317" height="180"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">634×360 36.6 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; foreground
...&gt; |&gt; Image.chroma_key! 
...&gt; |&gt; Image.preview()
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/a/b/ab1dcd6afd0e9423cabea461dea67940b2784f8a.png" data-download-href="https://forum.elixirforum.com/uploads/default/ab1dcd6afd0e9423cabea461dea67940b2784f8a" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/a/b/ab1dcd6afd0e9423cabea461dea67940b2784f8a.png" alt="image" data-base62-sha1="opLuVtG4JhKvcjRZemXTI0KuZ4K" width="317" height="180"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">634×360 28.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>Now we can compose this image over another image:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; background = Image.open!("./test/support/images/chroma_key/background.jpg", access: :random)
...&gt; Image.preview()
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/c/5/c5642a81c234f834d1713f1069e9cb44d3047470.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/c5642a81c234f834d1713f1069e9cb44d3047470" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/c/5/c5642a81c234f834d1713f1069e9cb44d3047470.jpeg" alt="image" data-base62-sha1="sacFjM2QqgRnDuUw6ASUHFzAYs8" width="320" height="184"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">640×368 47 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; Image.compose!(background, foreground) 
...&gt; |&gt; Image.preview()
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/f/7/f754550855a3898937023a12b9084553db60f576.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/f754550855a3898937023a12b9084553db60f576" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/f/7/f754550855a3898937023a12b9084553db60f576.jpeg" alt="image" data-base62-sha1="zhYCbY6UJFhFXWvjMgpPATtNmGa" width="320" height="184"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">640×368 45.9 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<h2><a name="p-265949-image-previews-3" class="anchor" href="#p-265949-image-previews-3" aria-label="Heading link" rel="nofollow"></a>Image Previews</h2>
<p>In the examples above you can see the use of <code>Image.preview/1</code> (and its short form <code>Image.p/1</code>). This function emits an image preview to <a href="https://iterm2.com" rel="nofollow">iTerm2</a> terminal windows. Its useful to import it into your <code>.iex.exs</code> file like this:</p>
<pre data-code-wrap="bash"><code class="lang-bash">% cat .iex.exs
import_if_available(Image, only: [p: 1, preview: 1])
</code></pre>
<h3><a name="p-265949-qrcode-encoding-4" class="anchor" href="#p-265949-qrcode-encoding-4" aria-label="Heading link" rel="nofollow"></a>QRcode encoding</h3>
<p>Leveraging the fabulous <a href="https://hex.pm/packages/evision" rel="nofollow">eVision</a> library by <a class="mention" href="/u/cocoa" rel="nofollow">@cocoa</a> (now on hex.pm!) there is both QRcode encoding and decoding. Encoding is new in this release of <code>Image</code>. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, qrcode} = Image.QRcode.encode("eVision, OpenCV, vix and libvips make for a great image processing experience for Elixir", size: 100)
iex&gt; Image.preview(qrcode)
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/6/c/6c3e33e5e3a131d9f7791402f80217350b89d4f2.png" data-download-href="https://forum.elixirforum.com/uploads/default/6c3e33e5e3a131d9f7791402f80217350b89d4f2" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/6/c/6c3e33e5e3a131d9f7791402f80217350b89d4f2.png" alt="image" data-base62-sha1="fryPNNwhNnL5ewPQMggfnnFF3Oy" width="301" height="301"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">402×402 682 Bytes</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<h2><a name="p-265949-full-changelog-for-image-0130-5" class="anchor" href="#p-265949-full-changelog-for-image-0130-5" aria-label="Heading link" rel="nofollow"></a>Full Changelog for Image 0.13.0</h2>
<h3><a name="p-265949-breaking-change-6" class="anchor" href="#p-265949-breaking-change-6" aria-label="Heading link" rel="nofollow"></a>Breaking change</h3>
<ul>
<li><code>Image.resize/3</code> renamed to <code>Image.thumbnail/3</code></li>
</ul>
<h3><a name="p-265949-bug-fixes-7" class="anchor" href="#p-265949-bug-fixes-7" aria-label="Heading link" rel="nofollow"></a>Bug fixes</h3>
<ul>
<li>
<p>Fix <code>Image.open/2</code> when opening JPEG images from a binary. Seems JPEG files agree on the <code>&lt;&lt;0xff, 0xd8, 0xff&gt;&gt;</code> header for the first three bytes. But not completely consistent with the following bytes.</p>
</li>
<li>
<p>Fix options for <code>Image.Draw</code> functions which are expected to be a map after validation (but were a keyword list).</p>
</li>
</ul>
<h3><a name="p-265949-enhancements-8" class="anchor" href="#p-265949-enhancements-8" aria-label="Heading link" rel="nofollow"></a>Enhancements</h3>
<ul>
<li>
<p>Add <code>Image.chroma_key/2</code> and <code>Image.chroma_mask/2</code>.</p>
</li>
<li>
<p>Add <code>Image.meme/3</code> and <code>Image.meme!/3</code>.</p>
</li>
<li>
<p>Add <code>Image.QRcode.encode/1</code> and <code>Image.QRcode.decode/1</code>.</p>
</li>
<li>
<p>Add <code>Image.blur/2</code>.</p>
</li>
<li>
<p>Add <code>Image.feather/2</code>.</p>
</li>
<li>
<p>Add <code>Image.new/2</code> that creates a new image of the same shape as the provided image.</p>
</li>
<li>
<p>Add <code>Image.resize/3</code>.</p>
</li>
<li>
<p>Add <code>Image.split_bands/1</code>.</p>
</li>
<li>
<p>Add <code>Image.if_then_else/3</code>.</p>
</li>
<li>
<p>Add <code>Image.preview/1</code> (and <code>Image.p/1</code> that delegates to it) to preview an image inline in an iTerm2 terminal windows.</p>
</li>
<li>
<p>Add <code>Image.split_bands/1</code> to return a list single band images, one for each band in the original image.</p>
</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265949" data-batch-url="/posts/batch_likers">
                        11
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-265949" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265949"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #31"></div>
  </section>
</div>
    <div class="postbit" id="265961" data-post-id="265961">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="derpycoder" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/120/31388_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  derpycoder
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is awesome!!!</p>
<p>I recently added Imgproxy + MinIO + Varnish.</p>
<p>Can this library replace what Imgproxy does or it is to be used alongside.</p>
<p>i.e. Imgproxy will be accessible directly using signed URL. And this library will be used for special use cases like Overlays, Meme Generation, streaming images, Greenscreen magic, etc.</p>
<p>P.S. I just love how much control this gives us. I’m just confused how to replace Imgproxy with this. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265961" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-265961" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265961"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #32"></div>
  </section>
</div>
    <div class="postbit" id="265962" data-post-id="265962">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thats the next library on my list (hmmmm, too many libraries on my list).  I’m tentatively calling it <code>Imagine</code> and it will provide image proxy, streaming, caching, use client hints for resizing and include all of the capabilities of <code>Image</code> (like overlays, composition, chroma keying, memes, etc etc etc).</p>
<p>All of the basic functionality is now in <code>Image</code> for all the things you mentioned.  Including streaming images from S3, processing them and streaming them out through Phoenix - all in parallel.  It will be very cool I think.  But its a couple of months away - the design is in my head but not in a repo.    Think a little bit like <a href="https://thumbor.readthedocs.io/en/latest/" rel="nofollow">Thumbor</a> but idiomatic for Elixir.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265962" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-265962" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265962"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #33"></div>
  </section>
</div>
    <div class="postbit" id="265963" data-post-id="265963">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="derpycoder" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/120/31388_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  derpycoder
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m going to use image library definitely. Post image creation will become super easy, so will memes.</p>
<p>Take inspiration from Imgproxy as well.</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://imgproxy.net/">
  <header class="source">
      <img src="https://imgproxy.net/favicon.ico" class="site-icon" alt="" width="48" height="48">

      <a href="https://imgproxy.net/" target="_blank" rel="noopener nofollow ugc">imgproxy.net</a>
  </header>

  <article class="onebox-body">
    <img width="360" height="360" src="https://imgproxy.net/social.png" class="thumbnail onebox-avatar" alt="">

<h3><a href="https://imgproxy.net/" target="_blank" rel="noopener nofollow ugc">imgproxy: fast and secure on-the-fly image processing</a></h3>

  <p>imgproxy is a fast and secure standalone server for resizing and converting remote images. The guiding principles behind imgproxy are security, speed, and simplicity</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>As it’s fastest of the lot:</p>
<p><a href="https://github.com/imgproxy/imgproxy/blob/master/BENCHMARK.md" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/imgproxy/imgproxy/blob/master/BENCHMARK.md</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265963" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-265963" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265963"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #34"></div>
  </section>
</div>
    <div class="postbit" id="265964" data-post-id="265964">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Very happy to do so. I’ll post when the repo is up - feedback and suggestions will be very welcome.</p>
<p>My reference to Thumbor wasn’t about architecture or performance, just basic problem domain and capability.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265964" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-265964" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265964"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #35"></div>
  </section>
</div>
    <div class="postbit" id="265965" data-post-id="265965">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>One thing I am clear on: configure it from hex and you’re good to go. No static configuration, no setup process (other than install <code>libvips</code>).  Be up and running in 30 seconds.  And after that a great developer experience and designer experience.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265965" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-265965" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265965"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #36"></div>
  </section>
</div>
    <div class="postbit" id="265966" data-post-id="265966">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="KiKi" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  KiKi
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This looks like a very promising library for the project I’m currently working on. In one of my previous projects I didn’t want to use Mogrify as it’s not really performant, instead, I used sharp (node library) which uses libvips to process images in combination with rambo (hex package) which allowed me to run node commands from elixir app.</p>
<p>I will give Image a try to see how it performs in real life, but just to get a better understanding, what would be the pros of using it compared to the sharp+rambo combo?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265966" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-265966" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265966"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #37"></div>
  </section>
</div>
    <div class="postbit" id="265967" data-post-id="265967">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think these would be the main differences.  I can’t really say if they are pros or cons for you. I can say though that <code>libvips</code> is amazing (but since you use Sharp you already know that), <a class="mention" href="/u/akash-akya" rel="nofollow">@akash-akya</a> wrote <a href="https://github.com/akash-akya/vix" rel="nofollow">vix</a> which is the NIF binding to <code>libvips</code> and its really well done.</p>
<h3><a name="p-265967-things-to-consider-1" class="anchor" href="#p-265967-things-to-consider-1" aria-label="Heading link" rel="nofollow"></a>Things to consider</h3>
<ul>
<li>
<p><code>Image</code> is a wrapper around <code>vix</code>/<code>libvips</code> which is written as a NIF so its as fast an integration as you can make.</p>
</li>
<li>
<p>The image binary data is <strong>never</strong> copied between Elixir-land and the native C-based NIF world. Big performance win. (Ok, two exceptions: (1) when specifically asking for the binary to be copied to an Elixir binary and (2) when streaming an image to a Phoenix <code>conn</code>)</p>
</li>
<li>
<p>Image data can be shared with <a href="https://hex.pm/packages/eVision" rel="nofollow">eVision</a> with zero-copy sharing of imaging data. And can also be shared with <a href="https://hex.pm/nx" rel="nofollow">Nx</a>.</p>
</li>
<li>
<p>Using NIFs introduces a reliability and security risk since that code falls outside the control of the BEAM. However in all my testing I’ve never had a segfault.</p>
</li>
<li>
<p>John Cupitt who maintains libvips is very active and supportive of both Image and Vix development (as he is with Sharp)</p>
</li>
<li>
<p>The functional orientation, immutability (with a small escape hatch), multi-threaded execution, small memory footprint and pipelined execution really fits well into the Elixir/BEAM operating model.</p>
</li>
<li>
<p>Image (because of Vix) supports image streaming both as a source and a sink.  So you can stream an image from S3, put it in a transformation pipeline and stream it to a Phoenix <code>conn</code> almost seamlessly and with good performance. The data is only copied from the NIF to the Phoenix <code>conn</code> on demand.</p>
</li>
</ul>
<p>Overall I would expect you would see lower latency using a NIF-based solution that a ports based one and you should find the threading model and pipeline process improving memory and CPU utilisation. This is speculation but Vix (the NIF to libvips) uses dirty threads to ensure its a good neighbour to the BEAM at the same time it can use BEAM scheduling and because of the way its memory is managed, very unlikely to have leaks or phantom processes.</p>
<p>Hope that helps, happy to answer any other questions or unknowns.  I probably sound like a fanboy but John Cupitt (libvips) and <a class="mention" href="/u/akash-akya" rel="nofollow">@akash-akya</a> (Vix) have really done an amazing job and Image just makes it more idiomatic for Elixir developers.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265967" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-265967" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265967"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #38"></div>
  </section>
</div>
    <div class="postbit" id="265968" data-post-id="265968">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h3><a name="p-265968-roadmap-to-version-10-1" class="anchor" href="#p-265968-roadmap-to-version-10-1" aria-label="Heading link" rel="nofollow"></a>Roadmap to Version 1.0</h3>
<p>It is and has always been my intention that this library is largely user driven for new requirements.  There are few additional capabilities I will add before 1.0 but after that I see it as “user driven”.  It’s built on the amazing <a href="https://hex.pm/packages/vix" rel="nofollow">Vix</a> and <a href="https://hex.pm/packages/evision" rel="nofollow">eVision</a> so <code>Image</code> should only concentrate on those functions which simplify complex transforms, makes common usage more idiomatic for Elixir developers or improve over all developer experience.</p>
<p>I think it is quite close. I’m expect to release 1.0 before end of 2022. The additional functions I will definitely implement before 1.0 are:</p>
<ul>
<li>
<p>Canny and Sobel edge detection</p>
</li>
<li>
<p>Object detection and tagging (based on eVision)</p>
</li>
<li>
<p>A complete set of free-standing live books as tutorials</p>
</li>
<li>
<p>Possibly (not committed) blob detection</p>
</li>
</ul>
<h3><a name="p-265968-community-feedback-2" class="anchor" href="#p-265968-community-feedback-2" aria-label="Heading link" rel="nofollow"></a>Community feedback</h3>
<p>Comments, suggestions very welcome.  It was <a class="mention" href="/u/genericjam" rel="nofollow">@GenericJam</a> that motivated implementation of <code>Image.meme/3</code> and <code>Image.chroma_key/2</code> and it was a blast doing those. I learned a lot.  Other ideas are very welcome.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265968" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-265968" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265968"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #39"></div>
  </section>
</div>
    <div class="postbit" id="265970" data-post-id="265970">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="derpycoder" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/120/31388_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  derpycoder
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I have some ideas I would like to share with you, since I can’t do them <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20">:</p>
<ol>
<li>Color palette detection, for theming purposes. (Like say a page displays an image, it can color itself based on the palette of the image, or it can be used for showing a dominant color, before the image loads.)</li>
<li>Color grading images based on LUT provided. (For consistent look and feel of the site)</li>
<li>Configurable QR code. (Like <a href="https://www.qrcode-monkey.com" rel="noopener nofollow ugc">QR code monkey</a>)</li>
<li>Rendering a HEEX template, a webpage or a section of a webpage, or svg into an image without using headless chrome if possible. (To allow creation of badges like <a href="http://shields.io" rel="noopener nofollow ugc">shields.io</a>, or run in LiveBook badge, or images that can be used in profiles like GitHub or Twitter or Linked, like <a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener nofollow ugc">GitHub Readme Stats</a>)</li>
<li>Video to gif or something better.</li>
<li>Some default / custom placeholder image in case of error.</li>
</ol>
<p>Documentation, Tutorial, interactive LiveBooks, Cheatsheet:</p>
<ol>
<li>For instance, how do I introduce a ML trained model to the pipeline. (E.g. Object detection using <a href="https://www.section.io/engineering-education/introduction-to-yolo-algorithm-for-object-detection/" rel="noopener nofollow ugc">YOLO ML Algo</a>, or Image scale using a machine model.)</li>
<li>How to introduce compression step into the pipeline.</li>
<li>General examples like the ones you have put in this discussion thread are missing in the official docs page. (I would have not been able to imagine such things are possible by looking at the API <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20">)</li>
</ol>
<hr>
<p>P.S. I skimmed through the API Documentation, so I don’t know if some of the suggestions are already possible. I hope there are examples in the future for every thing this library is capable of.</p>
<p>P.P.S. It’s incredible how many APIs are present in that library, so I feel ashamed asking for more. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="265970" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/image-an-image-processing-library-based-upon-vix/47568/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-265970" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="265970"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #40"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/47568/load_more?page=5">Load more posts (154 remaining)</a>
</div></template></turbo-stream>