<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="332559" data-post-id="332559">
  <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 had the opportunity to present at the Elixir Sydney Meetup in May. The video is now up on YouTube:</p>
<div class="youtube-onebox lazy-video-container" data-video-id="H-Psxgqoa-M" data-video-title="Fast and Efficient Image Processing in Elixir - Kip Cole" data-video-start-time="" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=H-Psxgqoa-M" target="_blank" class="video-thumbnail" rel="noopener nofollow">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/H-Psxgqoa-M/maxresdefault.jpg" title="Fast and Efficient Image Processing in Elixir - Kip Cole" width="690" height="388">
  </a>
</div>

<p>It’s not great production quality - largely because my MacBook died the night before with all the code uncommitted. I had to rebuild from scratch the next day.</p>
<p>The focus is primarily on what makes <code>libvips</code> such a good platform to build upon for Elixir. It’s very functional in its design - demand driven, immutable, composable and horizontally scalable. And compared to imagemagick, much more secure.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="332559" 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/153">Post #152</a>
	                </div>
	            </div>
              <div id="likers-container-332559" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="332559"
                     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 #152"></div>
  </section>
</div>
    <div class="postbit" id="332972" data-post-id="332972">
  <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 just published <a href="https://hex.pm/packages/image/0.50.0" rel="nofollow">Image version 0.50.0</a>. This was a fun release because it finally starts to deal with <a href="https://en.wikipedia.org/wiki/Color_difference" rel="nofollow">color difference</a> and <a href="https://www.alanzucconi.com/2015/09/30/colour-sorting/" rel="nofollow">color sorting</a>. It also implements <a href="https://en.wikipedia.org/wiki/K-means_clustering" rel="nofollow">K-means clustering</a> via the most excellent <a href="https://hex.pm/packages/scholar" rel="nofollow">Scholar</a> library.</p>
<p>Special thanks to <a class="mention" href="/u/mattmower" rel="nofollow">@mattmower</a> for the collaboration and motivation.</p>
<h3><a name="p-332972-livebook-demo-1" class="anchor" href="#p-332972-livebook-demo-1" aria-label="Heading link" rel="nofollow"></a>Livebook demo</h3>
<p>There is a new livebook in the repo that demonstrates these new functions and their purpose.</p>
<p><a href="https://livebook.dev/run?url=https%3A%2F%2Fraw.githubusercontent.com%2Felixir-image%2Fimage%2Fmain%2Flivebook%2Fcolor_clustering.livemd" rel="nofollow"><img src="https://livebook.dev/badge/v1/blue.svg" alt="Run in Livebook" width="170" height="40"></a></p>
<h3><a name="p-332972-enhancements-2" class="anchor" href="#p-332972-enhancements-2" aria-label="Heading link" rel="nofollow"></a>Enhancements</h3>
<ul>
<li>
<p>Updates <code>Image.dominant_color/2</code> to take an optional <code>:top_n</code> which indicates how many of the most dominant colors to return. The default is <code>1</code>. In addition, the implementation of <code>Image.dominant_color/2</code> has been simplified following the advice at <a href="https://github.com/libvips/libvips/discussions/4016" class="inline-onebox" rel="nofollow">How to sample the palette of an image · libvips/libvips · Discussion #4016 · GitHub</a></p>
</li>
<li>
<p>Adds <code>Image.delta_e/3</code> to calculate a difference between two colors using one of the CIE color difference algorithms.</p>
</li>
<li>
<p>Adds <code>Image.k_means/2</code> to cluster image colors into a color palette. This function is only available if <a href="https://hex.pm/packages/scholar" rel="nofollow">scholar</a> is configured. As for any <a href="https://hex.pm/packages/nx" rel="nofollow">Nx</a> installation, performance is affected by configuration options. It is likely that setting the following in <code>config.exs</code> will be a good idea:</p>
</li>
</ul>
<pre data-code-wrap="elixir"><code class="lang-elixir">config :nx,
  default_backend: EXLA.Backend

config :nx, :default_defn_options,
  compiler: EXLA
</code></pre>
<ul>
<li>
<p>Adds <code>Image.reduce_colors/2</code> to reduce the number of colors in an image. <code>Scholar.Cluster.KMeans.fit/2</code> is used to cluster the colors. The clusters are then used to recolor the image.</p>
</li>
<li>
<p>Adds <code>Image.Color.sort/2</code> to sort colors perceptually.</p>
</li>
<li>
<p>Adds <code>Image.Color.convert/3</code> to convert a color from one color space to another. Currently only supports <code>srgb_to_hsv</code>.</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="332972" data-batch-url="/posts/batch_likers">
                        9
                      </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/154">Post #153</a>
	                </div>
	            </div>
              <div id="likers-container-332972" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="332972"
                     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 #153"></div>
  </section>
</div>
    <div class="postbit" id="336179" data-post-id="336179">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello!</p>
<p>First of all, congratulations on the great library you have created! So far I have always enjoyed using it when I have had the chance.</p>
<p>Can I ask a question on a specific issue I am having? Maybe I am being an idiot here (usually is the case), but I cannot seem to authenticate with an IP camera stream.</p>
<p>I have used the Video.stream!() function to open the camera on my laptop - no problem.</p>
<p>But now the camera I have connected to the laptop requires account and password. I do have them, but fail to see how I can provide the values to the camera. I am pretty sure the empty video stream I am receiving is due to this issue.</p>
<p>Snippet of my code</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def capture_stream do
    IO.puts("Attempting to open video stream...")

    case Image.Video.stream!(@stream_url, []) do
      video_stream when is_list(video_stream) or is_function(video_stream) -&gt;
        IO.puts("Video stream opened successfully.")
        process_stream(video_stream)
      _ -&gt;
        IO.puts("Error opening video stream.")
        {:error, :invalid_stream}
    end
  end
</code></pre>
<p>I am not sure if this is the correct place to post this question. If it is not, please let me know so I can move it elsewhere.</p>
<p>Thank you!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="336179" 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/155">Post #154</a>
	                </div>
	            </div>
              <div id="likers-container-336179" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336179"
                     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 #154"></div>
  </section>
</div>
    <div class="postbit" id="336230" data-post-id="336230">
  <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/undeadko" rel="nofollow">@undeadko</a>, definitely not being an idiot. Anything video is hard.</p>
<p>As you know, <code>Image.Video</code> functions are idiomatic wrappers around the excellent <a href="https://hex.pm/packages/evision" rel="nofollow">evision</a> library which is an interface to <a href="https://opencv.org" rel="nofollow">OpenCV</a>.</p>
<p>It looks like authenticated streams are supported when using a camera that supports a streaming protocol, most likely <code>RTSP</code>. I found <a href="https://stackoverflow.com/questions/58999462/how-to-authenticate-to-ip-camera-using-opencv" rel="nofollow">this conversation</a> on Stackoverflow.  Hopefully that gives you a path to try.</p>
<p>Feel free to keep the conversation going here, or open a GitHub <a href="https://github.com/elixir-image/image/discussions" rel="nofollow">discussion</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="336230" 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/156">Post #155</a>
	                </div>
	            </div>
              <div id="likers-container-336230" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336230"
                     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 #155"></div>
  </section>
</div>
    <div class="postbit" id="337343" data-post-id="337343">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you <a class="mention" href="/u/kip" rel="nofollow">@kip</a> for another fantastic library. I’m using this today now to extract exif data from images my users upload. Really cool stuff! <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"> you made this very easy for me to implement.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337343" 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/157">Post #156</a>
	                </div>
	            </div>
              <div id="likers-container-337343" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337343"
                     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 #156"></div>
  </section>
</div>
    <div class="postbit" id="337356" data-post-id="337356">
  <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/undeadko" rel="nofollow">@undeadko</a>, I’m back at home now and tested authenticated RTSP streams - which works well based on my testing.</p>
<h3><a name="p-337356-install-evision-from-source-using-ffmpeg-1" class="anchor" href="#p-337356-install-evision-from-source-using-ffmpeg-1" aria-label="Heading link" rel="nofollow"></a>Install evision from source, using ffmpeg</h3>
<ol>
<li>Make sure you have <a href="https://ffmpeg.org" rel="nofollow">ffmpeg</a> installed. On MacOS that would be <code>brew install ffmpeg &amp;&amp; brew link ffmpeg</code> or similar.</li>
<li>You’ll need to build <a href="https://hex.pm/packages/evision" rel="nofollow">evision</a> from source by setting <code>export EVISION_PREFER_PRECOMPILED=false</code></li>
<li>Configure at least <a href="https://hex.pm/packages/evision/0.2.9" rel="nofollow">evision 0.2.9</a>. As I write this message that version isn’t yet on hex, but it’s on its way.</li>
<li>Start up <code>iex</code> which will trigger compilation of <code>evision</code> (that takes some time - grab a coffee) and then execute the following example.</li>
</ol>
<h3><a name="p-337356-example-rtsp-authenticated-stream-access-2" class="anchor" href="#p-337356-example-rtsp-authenticated-stream-access-2" aria-label="Heading link" rel="nofollow"></a>Example RTSP authenticated stream access</h3>
<pre data-code-wrap="elixir"><code class="lang-elixir"># Confirm that :ffmpeg is listed as an available video backend.
iex&gt; Image.Video.available_backends()
[:ffmpeg, :avfoundation, :opencv_mjpeg, :images]

iex&gt; rtsp_url = "rtsp://user_id:password@ip_address_or_dns_name"
iex&gt; {:ok, video} = Image.Video.open(rtsp_url, backend: :ffmpeg)
{:ok,
 %Evision.VideoCapture{
   fps: 25.0,
   frame_count: -2562047788015215.0,
   frame_width: 2304.0,
   frame_height: 1296.0,
   isOpened: true,
   ref: #Reference&lt;0.4047034452.1254752288.211903&gt;
 }}
iex&gt; {:ok, frame} = Image.Video.image_from_video(video)
{:ok, %Vix.Vips.Image{ref: #Reference&lt;0.4047034452.1254752292.212088&gt;}}
</code></pre>
<p>If you’re planning to stream frames, look at <a href="https://hexdocs.pm/image/Image.Video.html#stream!/2" rel="nofollow">Image.Video.stream!/2</a>.</p>
<p>I’ll add some documentation and publish a doc update to <code>image</code> over 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="337356" 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/158">Post #157</a>
	                </div>
	            </div>
              <div id="likers-container-337356" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337356"
                     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 #157"></div>
  </section>
</div>
    <div class="postbit" id="337369" data-post-id="337369">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/kip" rel="nofollow">@kip</a> First of all I would like to congratulate you for such a great contribution to the Elixir ecosystem not only with your libraries but with your precious advice.<br>
I’m currently working on a project that requires to compress video very aggressively and I was using Rust and some interesting codecs. But being a big fan of Elixir I decided I will try a PoC 100% Elixir based (except key dependencies but having Elixir wrappers). And Image library will be at the core of my PoCs as in fact I will treat the video stream as a stream of images.<br>
I will use several techniques and one of them is to remove colors from frames before sending them (except for some key sample ones), and then, at the consumer I will recolor them based on the key sample frames that I sent interpolated depending on the use case 1 in 10 or 1 in 100 or even 1 in 1000.<br>
Is there any approach that you would recommend using Image or is this something in your roadmap?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337369" 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/159">Post #158</a>
	                </div>
	            </div>
              <div id="likers-container-337369" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337369"
                     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 #158"></div>
  </section>
</div>
    <div class="postbit" id="337416" data-post-id="337416">
  <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 kind words, it help motivate improvements and support for sure.</p>
<p>I think, for your use case, <code>image</code> (and <code>libvips</code>) are probably not the right tools. They may have some value in some parts, but overall if you’re looking to stream, quantize and recolour in anything near real time, <code>image</code> isn’t the right tool.</p>
<ul>
<li><code>evision</code>, even with <code>ffmpeg</code> doesn’t give you access to the raw video frame.</li>
<li>Raw video is often encoded in <a href="https://en.wikipedia.org/wiki/Y%E2%80%B2UV" rel="nofollow">Y’UV format</a> and while there is <a href="https://hexdocs.pm/image/Image.YUV.html" rel="nofollow">Image.YUV</a> its not fast enough for heavy real time processing.  You get a budget of maybe 30ms after decoding and then reencoding.  See <a href="https://github.com/elixir-image/image/discussions/121" rel="nofollow">this discussion</a> for more context.</li>
<li>I believe you’ll have more success in Elixir looking at what <a href="https://membrane.stream" rel="nofollow">Membrane framework</a> offers. It has the right conceptual model for streaming and processing video and the team is very helpful.</li>
<li>For recolouring it will be best to work with <a href="https://en.wikipedia.org/wiki/Quantization_(image_processing)" rel="nofollow">quantised</a> image formats. That way you are only changing the palette to do the recolouring. And quantising the frames is one of the best ways to compress video. Quantising and subsampling (like YUV) are two of the best techniques for that, And then you get into key frames and delta frames which is well beyond the scope of <code>image</code>. Today, <code>libvips</code> doesn’t have a pubic api to <code>libimagequant</code> that is used internally. Since you’re already using Rust, I suspect <a href="https://pngquant.org/lib/" rel="nofollow">libimagequant</a> is a good choice for your needs too.</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="337416" 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/160">Post #159</a>
	                </div>
	            </div>
              <div id="likers-container-337416" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337416"
                     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 #159"></div>
  </section>
</div>
    <div class="postbit" id="338951" data-post-id="338951">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Does Image support PDF?</p>
<p>Vips says it supports pdf:</p>
<blockquote>
<p>Images can have any number of bands. It supports a good range of image formats, including JPEG, JPEG2000, JPEG-XL, TIFF, PNG, WebP, HEIC, AVIF, FITS, Matlab, OpenEXR, PDF, SVG, HDR, PPM / PGM / PFM, CSV, GIF, Analyze, NIfTI, DeepZoom, and OpenSlide.</p>
</blockquote>
<ul>
<li><a href="https://github.com/libvips/libvips" class="inline-onebox" rel="noopener nofollow ugc">GitHub - libvips/libvips: A fast image processing library with low memory needs. · GitHub</a></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="338951" 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/161">Post #160</a>
	                </div>
	            </div>
              <div id="likers-container-338951" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="338951"
                     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 #160"></div>
  </section>
</div>
    <div class="postbit" id="338953" data-post-id="338953">
  <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>Yes, but only as an image container. Which means that if you call <code>Image.open/2</code> on a PDF file, then each page will be an <code>Vix.Vips.Image.t</code>. There is nothing in <code>libvips</code> that parses the contents of a PDF file as structured data. The obverse is true for writing PDF files.</p>
<p>I don’t believe the prebuilt <code>libvips</code> library has PDF support built in so you may have to:</p>
<pre data-code-wrap="bash"><code class="lang-bash">VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS mix deps.compile vix
</code></pre>
<p>Making sure you’ve installed <code>libvips</code> first (on MacOS, <code>brew install libvips</code> for example).</p> 
	            </div>

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