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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There’s <code>mix compile --no-optional-deps --warnings-as-errors</code> to make sure that the application compiles successfully without optional dependencies present. Sounds like that would be useful to have in CI.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="274225" 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/83">Post #82</a>
	                </div>
	            </div>
              <div id="likers-container-274225" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="274225"
                     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 #82"></div>
  </section>
</div>
    <div class="postbit" id="274226" data-post-id="274226">
  <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>Arrggghhhh. Fixed in <a href="https://hex.pm/packages/image/0.22.1" rel="nofollow">Image version 0.22.1</a>.  Thanks for the report of this authors idiocy!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="274226" 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/84">Post #83</a>
	                </div>
	            </div>
              <div id="likers-container-274226" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="274226"
                     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 #83"></div>
  </section>
</div>
    <div class="postbit" id="274228" data-post-id="274228">
  <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>Yep, I certainly need to take some time to configure CI properly.  That’s a chore I find hard to prioritise but you’re right.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="274228" 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/85">Post #84</a>
	                </div>
	            </div>
              <div id="likers-container-274228" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="274228"
                     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 #84"></div>
  </section>
</div>
    <div class="postbit" id="276402" data-post-id="276402">
  <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 just published <a href="https://hex.pm/packages/image/0.23.0" rel="nofollow">Image version 0.23.0</a> with the following improvements and bug fixes.  In particular <code>Image.normalize/1</code> and <code>Image.autolevel/1</code> are steps towards automated image improvement.</p>
<h3><a name="p-276402-bug-fixes-1" class="anchor" href="#p-276402-bug-fixes-1" aria-label="Heading link" rel="nofollow"></a>Bug Fixes</h3>
<ul>
<li>
<p>Fix specs for <code>Image.Options.Write</code>. Thanks to <span class="mention">@jarrodmoldrich</span>. Closes <span class="hashtag-raw">#36</span>.</p>
</li>
<li>
<p>Fix spec for <code>Image.exif/1</code>. Thanks to <a class="mention" href="/u/ntodd" rel="nofollow">@ntodd</a> for the PR. Closes <span class="hashtag-raw">#35</span>.</p>
</li>
</ul>
<h3><a name="p-276402-enhancements-2" class="anchor" href="#p-276402-enhancements-2" aria-label="Heading link" rel="nofollow"></a>Enhancements</h3>
<ul>
<li>
<p>Adds <code>Image.normalize/1</code> which normalizes an image by expanding the luminance of an image to cover the full dynamic range.</p>
</li>
<li>
<p>Adds <code>Image.autolevel/1</code> which scales each band of an image to fit the full dynamic range. Unlike <code>Image.normalize/1</code>, each band is scaled separately.</p>
</li>
<li>
<p>Adds <code>Image.erode/2</code> which erodes pixels from the edge of an image mask. This can be useful to remove a small amount of colour fringing around the edge of an image.</p>
</li>
<li>
<p>Adds <code>Image.dilate/2</code> which dilates pixels from the edge of an image mask.</p>
</li>
<li>
<p>Adds <code>Image.trim/2</code> which trims an image to the bounding box of the non-background area.</p>
</li>
<li>
<p>Adds <code>Image.flatten/1</code> which flattens an alpha layer out of an image</p>
</li>
<li>
<p><code>Image.Options.Write.validate_options/2</code> now validates options appropriate to each image type in order to make validation more robust.</p>
</li>
<li>
<p>Adds <code>:minimize_file_size</code> option to <code>Image.write/2</code> for JPEG and PNG files which if <code>true</code> will apply a range of techniques to minimize the size of the image file at the expense of time to save the image and potentially image quality.</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="276402" data-batch-url="/posts/batch_likers">
                        13
                      </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/86">Post #85</a>
	                </div>
	            </div>
              <div id="likers-container-276402" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="276402"
                     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 #85"></div>
  </section>
</div>
    <div class="postbit" id="282123" data-post-id="282123">
  <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>Today is object detection Sunday.  Greatly inspired by the <a href="https://www.youtube.com/watch?v=OsxGB6MbA8o&amp;t=1s" rel="nofollow">fabulous talk</a> by <a class="mention" href="/u/hansihe" rel="nofollow">@hansihe</a> at the Warsaw Elixir Meetup earlier this month I transcribed his live coding example and implemented it in a new experimental module, <a href="https://github.com/elixir-image/image/blob/detect/lib/image/detection.ex" rel="nofollow">Image.Detection</a>.</p>
<p>Based upon his solid observations I also added some quality of life improvements to the <code>detect</code> branch of  <code>Image</code>:</p>
<ul>
<li><code>Image.from_kino/2</code> and <code>Image.from_kino!/2</code> to easily consume the image data from a <code>Kino.Input.Image</code> data source in <a href="https://livebook.dev" rel="nofollow">Livebook</a></li>
<li><code>Image.Shape.rect/3</code> and <code>Image.Shape.rect!/3</code> to have a composable way to draw rectangles - specifically object bounding boxes in this case.</li>
<li><code>Image.embed/4</code> and <code>Image.embed!/4</code> to make it much easier to conform an image to the dimensions required by an ML model.</li>
</ul>
<p>The code is ready for fun and experimentation. Given some of the tricky dependency configuration at the moment it can only be used as a GitHub dependency for now. You can add it in a <code>mix.exs</code> as:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{:image, github: "elixir-image/image", branch: "detect"}`
</code></pre>
<h3><a name="p-282123-demo-example-1" class="anchor" href="#p-282123-demo-example-1" aria-label="Heading link" rel="nofollow"></a>Demo example</h3>
<p>Livebook coming this week!</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; i = Image.open!("./test/support/images/elixir_warsaw_meetup.png")
%Vix.Vips.Image{ref: #Reference&lt;0.3196308165.1633288229.90166&gt;}
iex&gt; Image.Detection.detect(i)
{:ok, %Vix.Vips.Image{ref: #Reference&lt;0.3196308165.1633288229.90638&gt;}}
</code></pre>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/1/8/18aa743fdaa525be5a73bcc06c9a42438ee6d170.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/18aa743fdaa525be5a73bcc06c9a42438ee6d170" title="elixir_warsaw_detected" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/1/8/18aa743fdaa525be5a73bcc06c9a42438ee6d170.jpeg" alt="elixir_warsaw_detected" data-base62-sha1="3wcEDNq6Bj5yug2Pkm6nfkprovm" width="480" height="358"><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">elixir_warsaw_detected</span><span class="informations">640×478 42.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>
<h3><a name="p-282123-the-code-2" class="anchor" href="#p-282123-the-code-2" aria-label="Heading link" rel="nofollow"></a>The code</h3>
<p>Its amazing how little code this takes with <code>Nx</code>, <code>Axon</code> and <code>Axon Onnx</code>.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def detect(%Vimage{} = image, model_path \\ default_model_path()) do
    # Import the model and extract the
    # prediction function and its parameters.
    {model, params} = AxonOnnx.import(model_path)
    {_init_fn, predict_fn} = Axon.build(model, compiler: EXLA)

    # Flatten out any alpha band then resize the image
    # so the longest edge is the same as the model size,
    # then add a black border to expand the shorter dimension
    # so the overall image conforms to the model requirements.
    prepared_image =
      image
      |&gt; Image.flatten!()
      |&gt; Image.thumbnail!(@yolo_model_image_size)
      |&gt; Image.embed!(@yolo_model_image_size, @yolo_model_image_size)

    # Move the image to Nx. This is nothing more
    # than moving a pointer under the covers
    # so its efficient. Then conform the data to
    # the shape and type required for the model.
    # Last we add an additional axis that represents
    # the batch (we use only a batch of 1).
    batch =
      prepared_image
      |&gt; Image.to_nx!()
      |&gt; Nx.transpose(axes: [2, 0, 1])
      |&gt; Nx.as_type(:f32)
      |&gt; Nx.divide(255)
      |&gt; Nx.new_axis(0)

    # Run the prediction model, extract
    # the only batch that was sent
    # and transpose the axis back to
    # {width, height} layout for further
    # image processing.
    result =
      predict_fn.(params, batch)[0]
      |&gt; Nx.transpose(axes: [1, 0])

    # Filter the data by certainty,
    # zip with the class names, draw
    # bounding boxes and labels and the
    # trim off the extra pixels we added
    # earlier to get back to the original
    # image shape.
    result
    |&gt; Yolo.NMS.nms(0.5)
    |&gt; Enum.zip(classes())
    |&gt; draw_bbox_with_labels(prepared_image)
    |&gt; Image.trim()
  end
</code></pre>
<h3><a name="p-282123-next-steps-3" class="anchor" href="#p-282123-next-steps-3" aria-label="Heading link" rel="nofollow"></a>Next steps</h3>
<p>This is a proof-of-concept only. The API will almost certainly change - not all use cases require painting a bounding box with labels.  Feedback however is most welcome!.</p>
<p>Thanks again to <a class="mention" href="/u/hansihe" rel="nofollow">@hansihe</a>, the work is all his.</p> 
	            </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Is there anywhere I can see a full script for this? I tried to get it running in Livebook and a newly created mix project but cant get the dependenies right <img src="https://forum.elixirforum.com/images/emoji/apple/upside_down_face.png?v=15" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" 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="282128" 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/88">Post #87</a>
	                </div>
	            </div>
              <div id="likers-container-282128" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282128"
                     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 #87"></div>
  </section>
</div>
    <div class="postbit" id="282131" data-post-id="282131">
  <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>Sure, it’s referenced in the post in the config line for mix.ibex’s and link behind the Image,Detection link. Just look at the <code>detect</code> branch at <a href="https://github.com/elixir-image/image%60" rel="nofollow">https://github.com/elixir-image/image`</a>.</p>
<p>I had to do quite some munging to get the deps right too hence the GitHub dependencies.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282131" 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/89">Post #88</a>
	                </div>
	            </div>
              <div id="likers-container-282131" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282131"
                     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 #88"></div>
  </section>
</div>
    <div class="postbit" id="282134" data-post-id="282134">
  <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’ve made a simple Livebook to demonstrate how to install, configure and do object detection:</p>
<p><a href="https://livebook.dev/run?url=https%3A%2F%2Fraw.githubusercontent.com%2Felixir-image%2Fimage_detection%2Fmain%2Flivebooks%2Fobject_detection.livemd" rel="nofollow"><img src="https://livebook.dev/badge/v1/blue.svg" alt="Run in Livebook" width="170" height="40"></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="282134" data-batch-url="/posts/batch_likers">
                        2
                      </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/90">Post #89</a>
	                </div>
	            </div>
              <div id="likers-container-282134" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282134"
                     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 #89"></div>
  </section>
</div>
    <div class="postbit" id="282153" data-post-id="282153">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Is there an easy way to make a copy of a mutable Image? I looked around the docs for something, but I couldn’t find anything. That’s the reason I used the closure to make images for drawing in the talk.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282153" 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/91">Post #90</a>
	                </div>
	            </div>
              <div id="likers-container-282153" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282153"
                     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 #90"></div>
  </section>
</div>
    <div class="postbit" id="282162" data-post-id="282162">
  <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/hansihe" rel="nofollow">@hansihe</a>, A mutable image is already copied for you and operations are serialised behind a genserver. So it is mutable - but only by you. And all operations are serialised so it’s also thread safe.</p>
<p>You can perform multiple mutations on a single copy of the image by using <code>Image.mutuate/2</code> (I have just <a href="https://github.com/elixir-image/image/blob/detect/lib/image.ex#L5430-L5496" rel="nofollow">updated the documentation on Image.mutate/2</a> quite a bit to make this clearer).</p>
<h3><a name="p-282162-mutation-example-1" class="anchor" href="#p-282162-mutation-example-1" aria-label="Heading link" rel="nofollow"></a>Mutation example</h3>
<pre data-code-wrap="elixir"><code class="lang-elixir"># The image is copied and operations
# are serialized behind a genserver.
# Only one copy is made but all operations
# will be serialized behind a genserver.
# When the function returns the genserver
# is broken down and the underlying
# mutated `t:Vix.Vips.Image.t/0` is returned.

iex&gt; Image.mutate image, fn mutable_image -&gt;
...&gt;  mutable_image
...&gt;  |&gt; Image.Draw.rect!(0, 0, 10, 10, color: :red)
...&gt;  |&gt; Image.Draw.rect!(2, 20, 10, 10, color: :green)
...&gt;  |&gt; Image.Draw.rect!(50, 50, 10, 10, color: :blue)
...&gt; end
</code></pre>
<p>By wrapping multiple mutations in an <code>Image.mutate/2</code> call there should be performance improvements - although for safety each mutation is still serialised through a genserver.</p> 
	            </div>

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