<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="250399" data-post-id="250399">
  <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 class="mention" href="/u/andrewdryga" rel="nofollow">@AndrewDryga</a> sounds very interesting, and I’d be happy to collaborate on that is its useful to you.  I have a similar motivation - next up in the list is another library I’m calling <code>Imagine</code> that is basically a plug to serve images using <code>Image</code> that can be very easily added to any Plug or Phoenix application.  A sort of a mix of <a href="https://github.com/thumbor/thumbor" rel="nofollow">thumbor</a> and <a rel="nofollow">Cloudinary</a>. But dead simple to add to an Elixir application and really easy to use.</p>
<p><code>Imagine</code> is also going to make strong use of <a href="https://wicg.github.io/responsive-image-client-hints/" rel="nofollow">Image Client Hints</a> that I think is the next big breakthrough in efficiency of web images.</p>
<p>Oh, and of course since you’re already knee-deep in image processing, using <code>Vix</code> is a great idea, its fabulous.  It takes a bit of effort to bridge between <code>libvips</code> terminology, the <code>Vix</code> implementation and your requirements but its not difficult.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250399" data-batch-url="/posts/batch_likers">
                        8
                      </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/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-250399" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250399"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="250402" data-post-id="250402">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="AndrewDryga" data-post="11" data-topic="47568">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/andrewdryga/48/2784_2.png" class="avatar"> AndrewDryga:</div>
<blockquote>
<p>. We don’t need external services.</p>
</blockquote>
</aside>
<p>I was not suggesting to use external services, just trying to exemplify with the example I gave if that was what you were looking for.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250402" 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/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-250402" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250402"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="250582" data-post-id="250582">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mayel" data-post="5" data-topic="47568">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mayel/48/26431_2.png" class="avatar"> mayel:</div>
<blockquote>
<p>I would prefer having the option to shell out rather than using the NIF when dealing with user-uploaded images</p>
</blockquote>
</aside>
<p>Apart from what <a class="mention" href="/u/kip" rel="nofollow">@kip</a> already mentioned, vips command currently only allows one operation per execution. So if we need to run more than one operation, we have to run multiple commands. This miss out on almost all the optimizations and performance gain libvips provides, I think performance is the reason people switch to libvips from ImageMagick. There is also reusing the intermediate result aspect. With shelling out, we can’t do any of that.</p>
<p>But if you only have one operation, and you are okay with trading performance for safety, it’s straight forward to wrap vips command. We can even stream results using libraries which support streaming commands. Like  <code>ex_cmd</code> or <code>exile</code> [Disclaimer: I’m the author of these two libraries]</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">input = File.stream!("foo.jpg")

# takes stream as input and returns stream as output
output = ExCmd.stream!(~w(vips invert stdin .png), input: input)

Stream.into(output, File.stream!("inverted_foo.png"))
|&gt; Stream.run()
</code></pre>
<p>You can spawn shell and pipe output across commands too</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">cmd = "vips invert stdin .png | vips gaussblur stdin .png 1.5"
output = ExCmd.stream!(["sh", "-c", cmd), input: input)
</code></pre>
<hr>
<blockquote>
<p>will you also add functions to load images from Memory, and will the S3-thing be a behaviour so other backends (such as GCS) can be added as well</p>
</blockquote>
<p><a class="mention" href="/u/jeroenvisser101" rel="nofollow">@jeroenvisser101</a> If you are okay with shelling out and if your pipeline is simple, you can already achieve this like I mentioned above. But of course, you would miss out on all the features and heavy lifting <code>Image</code> library brings.</p>
<p><em>Disclaimer: I’m the author of Vix</em></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250582" data-batch-url="/posts/batch_likers">
                        8
                      </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/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-250582" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250582"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="250697" data-post-id="250697">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for your response <a class="mention" href="/u/akash-akya" rel="nofollow">@akash-akya</a>, that was helpful <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_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="250697" 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/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-250697" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250697"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="250707" data-post-id="250707">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>great work (as always!) <a class="mention" href="/u/kip" rel="nofollow">@kip</a> - and especially <a class="mention" href="/u/akash-akya" rel="nofollow">@akash-akya</a> for the vix library..</p>
<p>we should also see about upstreaming first class support to waffle, I’m currently using waffle and vix using this one-line patch <a href="https://github.com/elixir-waffle/waffle/issues/76#issuecomment-921737534" class="inline-onebox" rel="noopener nofollow ugc">ExOptimizer Integration? · Issue #76 · elixir-waffle/waffle · GitHub</a></p>
<blockquote>
<p>defp apply_transformation(file, {:custom_func, func}), do: func.(file)</p>
</blockquote>
<p>notice how pngs stay pngs and jpgs stay jpgs, also experimenting with pdf thumbnails - but I believe waffle really wants to know the file extension as in their convert api (notice last :png atom):<br>
<code>{:convert, "-strip -thumbnail 250x250^ -gravity center -extent 250x250 -format png", :png}</code></p>
<p>great performance benefits with vix <img src="https://forum.elixirforum.com/images/emoji/apple/tada.png?v=15" title=":tada:" class="emoji" alt=":tada:" loading="lazy" width="20" height="20"></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defp generate_thumb(file, width) do
    case Vix.Vips.Foreign.find_load(file.path) do
      {:ok, "VipsForeignLoadPng" &lt;&gt; _kind} -&gt;
        {:ok, resized_img} = Vix.Vips.Operation.thumbnail(file.path, width, size: :VIPS_SIZE_DOWN)

        new_path = Waffle.File.generate_temporary_path(".png")

        case Vix.Vips.Operation.pngsave!(resized_img, new_path,
               strip: true,
               palette: true,
               effort: 10,
               bitdepth: 8,
               compression: 9,
               Q: 100
             ) do
          :ok -&gt;
            new_file = %Waffle.File{file | path: new_path, is_tempfile?: true}
            {:ok, new_file}

          _ -&gt;
            {:error, "It wasn't possible to generate a thumbnail"}
        end

      {:ok, "VipsForeignLoadJpeg" &lt;&gt; _kind} -&gt;
        {:ok, resized_img} = Vix.Vips.Operation.thumbnail(file.path, width, size: :VIPS_SIZE_DOWN)
        new_path = Waffle.File.generate_temporary_path(".jpg")

        case Vix.Vips.Operation.jpegsave!(resized_img, new_path,
               strip: true,
               "optimize-coding": true,
               Q: 85,
               interlace: false,
               "optimize-scans": true
             ) do
          :ok -&gt;
            new_file = %Waffle.File{file | path: new_path, is_tempfile?: true}
            {:ok, new_file}

          _ -&gt;
            {:error, "It wasn't possible to generate a thumbnail"}
        end

      {:ok, "VipsForeignLoadPdf" &lt;&gt; _kind} -&gt;
        {:ok, resized_img} = Vix.Vips.Operation.thumbnail(file.path, width, size: :VIPS_SIZE_DOWN)
        new_path = Waffle.File.generate_temporary_path(".jpg")

        case Vix.Vips.Operation.jpegsave!(resized_img, new_path,
               strip: true,
               "optimize-coding": true,
               Q: 85,
               interlace: false,
               "optimize-scans": true
             ) do
          :ok -&gt;
            new_file = %Waffle.File{file | path: new_path, is_tempfile?: true}
            {:ok, new_file}

          _ -&gt;
            {:error, "It wasn't possible to generate a thumbnail"}
        end

      unknown_loader -&gt;
        IO.inspect(unknown_loader)
        {:error, "unknown format - only png/jpg supported"}
    end
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250707" 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/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-250707" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250707"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="250712" data-post-id="250712">
  <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 class="mention" href="/u/exadra37" rel="nofollow">@Exadra37</a> well, I couldn’t help myself so I put some work into an API for text and shape overlays.  Not quite ready for formal release yet but its available to try from GitHub in the <a href="https://github.com/kipcole9/image/tree/text" rel="nofollow">text branch</a>. These demos are in the <a href="https://github.com/kipcole9/image/blob/text/lib/image/demo.ex" rel="nofollow">lib/demo.ex</a> file.</p>
<h3><a name="p-250712-reproducing-the-example-1" class="anchor" href="#p-250712-reproducing-the-example-1" aria-label="Heading link" rel="nofollow"></a>Reproducing the example</h3>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/1/0/10175b9fb01a7992b0f11b7195b8c4620968fae6.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/10175b9fb01a7992b0f11b7195b8c4620968fae6" title="polygon" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/1/0/10175b9fb01a7992b0f11b7195b8c4620968fae6.jpeg" alt="polygon" data-base62-sha1="2ilGnN5HQ9wnbdjBhMCE12WLLgy" width="690" height="407" data-dominant-color="588EA9"><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">polygon</span><span class="informations">1000×590 64.7 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>The code that produced this is:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def demo1 do
    {:ok, base_image} = Image.open("test/support/images/Singapore-2016-09-5887.jpg")
    {:ok, polygon} = Shape.polygon(@points, fill_color:  @polygon_color, stroke_color: "none", height: Image.height(base_image), opacity: 0.8)
    {:ok, explore_new} = Text.new_from_string("EXPLORE NEW", font_size: 95, font: "DIN Alternate")
    {:ok, places} = Text.new_from_string("PLACES", font_size: 95, font: "DIN Alternate")
    {:ok, blowout} = Text.new_from_string("BLOWOUT SINGAPORE SALE", font_size: 40, font: "DIN Alternate")
    {:ok, start_saving} = Text.new_from_string("START SAVING", font_size: 30, padding: 20, background_fill_color: "none", background_stroke_color: "white", background_stroke_width: 5)

    base_image
    |&gt; Image.compose!(polygon, x: :middle, y: :top)
    |&gt; Image.compose!(explore_new, x: 260, y: 200)
    |&gt; Image.compose!(places, x: 260, y: 260)
    |&gt; Image.compose!(blowout, x: 260, y: 340)
    |&gt; Image.compose!(start_saving, x: 260, y: 400)
    |&gt; Image.write!("/Users/kip/Desktop/polygon.png")
  end
</code></pre>
<h3><a name="p-250712-simple-text-overlay-2" class="anchor" href="#p-250712-simple-text-overlay-2" aria-label="Heading link" rel="nofollow"></a>Simple Text Overlay</h3>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/5/c/5c79a208f29cd055e466769335c9e9868f830500.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/5c79a208f29cd055e466769335c9e9868f830500" title="center_text" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/5/c/5c79a208f29cd055e466769335c9e9868f830500.jpeg" alt="center_text" data-base62-sha1="dc4wwQcQaBm8W2yemuGz6tN9kPK" width="690" height="407" data-dominant-color="3E5972"><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">center_text</span><span class="informations">1000×590 77.5 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>Which is created with:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def demo3 do
    {:ok, base_image} = Image.open("test/support/images/Singapore-2016-09-5887.jpg")
    {:ok, singapore} = Text.new_from_string("Singapore", font_size: 100, font: "DIN Alternate")

    base_image
    |&gt; Image.compose!(singapore, x: :center, y: :middle)
    |&gt; Image.write!("/Users/kip/Desktop/center_text.png")
  end
</code></pre>
<h3><a name="p-250712-transparent-text-3" class="anchor" href="#p-250712-transparent-text-3" aria-label="Heading link" rel="nofollow"></a>Transparent Text</h3>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/9/f/9fae66e0f5b98d489a50dc553bba4fbf3146becc.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/9fae66e0f5b98d489a50dc553bba4fbf3146becc" title="overlay" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/9/f/9fae66e0f5b98d489a50dc553bba4fbf3146becc.jpeg" alt="overlay" data-base62-sha1="mMBzt5PU2vTPsqfHypUcbN6rA4s" width="690" height="407" data-dominant-color="1B2630"><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">overlay</span><span class="informations">1000×590 47.4 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>This one is quite fun. Reversed text, full screen overlay with transparency. Created with:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def demo2 do
    {:ok, base_image} = Image.open("test/support/images/Singapore-2016-09-5887.jpg")
    {:ok, singapore} = Text.new_from_string("SINGAPORE", font_size: 250, font: "DIN Alternate", padding: base_image, text_fill_color: :transparent, background_fill_color: "black", background_fill_opacity: 0.6)

    base_image
    |&gt; Image.compose!(singapore)
    |&gt; Image.write!("/Users/kip/Desktop/overlay.png")
  end
</code></pre>
<p>Should be able to have both text overlays and shape overlays finished on the weekend.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250712" data-batch-url="/posts/batch_likers">
                        30
                      </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/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-250712" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250712"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="250753" data-post-id="250753">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I really love how straight forward the code looks to achieve the somewhat complex layered results. So nice!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250753" 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/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-250753" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250753"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="250759" data-post-id="250759">
  <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>Thanks for the feedback!  If you liked that, here’s the version that uses relative positioning which is much more intuitive to use and produces the same image as the first example above:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def demo4 do
    ....

    base_image
    |&gt; compose!([
      {polygon, x: 250, y: 0},
      {explore_new, y_baseline: :top, x_baseline: :left, dx: 20, dy: 200},
      {places, dy: 10},
      {blowout, dy: 20},
      {start_saving, dy: 50}
    ])
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250759" 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/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-250759" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250759"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="250761" data-post-id="250761">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Very nice, though I actually think I prefer the almost builder-pattern approach of piping each layer to the next function. Makes it very clear how the image is being built.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250761" 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/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-250761" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250761"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="250766" data-post-id="250766">
  <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 tend to agree with you. There is room for both approaches:</p>
<ol>
<li>As you say, the pipeline approach is the easiest to reason about and the most idiomatic</li>
<li>The composition list is the most efficient since it results in a single NIF call. However the actual compositing of the image is the dominant time factor</li>
<li>The composition list approach makes it much easier to build a composition programmatically - since its just a list.</li>
</ol>
<p>Both function signatures are now merged into master and will be release this weekend. Then .. back to image streaming (which I think is a “big deal”) for many apps.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="250766" data-batch-url="/posts/batch_likers">
                        10
                      </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/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-250766" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="250766"
                     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 #20"></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=3">Load more posts (174 remaining)</a>
</div></template></turbo-stream>