derpycoder
Image.write for WebP file, doesn't resize the images, unlike .pngs
Hey @kip,
After admiring your work on Image library for a long time, I finally got a chance to use it in my project.
I have a mix task, that compiles the images from assets/images/* directory and puts them into priv/images/* directory.
It creates different variations for input images.
defmodule Mix.Tasks.Images.Compile do
@moduledoc "Compile all images of projects, inspired by Benjamin Milde's elixir blog."
@shortdoc "Compiles images"
use Mix.Task
@assets_folder "assets/images/"
@image_sizes [300, 720, 960, 1200, 2000]
@impl Mix.Task
def run(_args) do
src_paths =
(@assets_folder <> "**/*.{png,webp,jpeg,jpg}")
|> Path.wildcard()
|> dbg()
for src_path <- src_paths, size <- @image_sizes do
file_name = src_path |> Path.rootname() |> Path.basename()
ext = src_path |> Path.extname()
path = src_path |> Path.split() |> Enum.drop(1) |> Path.join()
dest_dir = "priv/static" |> Path.join(path) |> Path.dirname()
dest_path = "#{dest_dir}/#{file_name}@#{size}#{ext}"
{:ok, thumb} = Image.thumbnail(src_path, size)
File.mkdir_p!(dest_dir)
Image.write(thumb, dest_path,
quality: 70,
strip_metadata: true,
minimize_file_size: true,
compression: 6
)
end
end
end
This produces following output: (For PNGs)
However, when I run the same code on WebP, it doesn’t work! Filename, may have changed, but the sizes remain the same.
What is your thoughts on tools like imgproxy?
After resize was done, I was thinking pre-compiling led to unnecessary resizing. For instance for images that are smaller than 500px, was being stretched to 1200px needlessly.
I will have to segregated folders and selectively resize them to different sizes, instead of resizing at runtime like imageproxy does.
Marked As Solved
kip
@derpycoder I just fixed a bug whereby :minimize_file_size wasn’t correctly applying :"min-size" option when writing a .webp image. That might help resolve the .webp image file size issue. I’ve not published an update to hex yet, I want to do some more testing with the updated evision that was just published first.
Also Liked
kip
I am working (slowly) on a similar capability in a separate library. I’m currently working on:
image_plugto provide a basic plug for serving images using a URL format similar toimgproxy.image_cacheto provide a caching layer over the top ofimage_plug.image_componentsto provide a live viewimagecomponent.colorto provide a standalone color library thatimagewill then use.
I can’t estimate when they’ll be done but I will get them done.
That’s very strange! If you’re able to provide me an image example I’ll very happily take a look at it.
kip
I have pushed a commit that does what you proposed, but in keyword list format. For example:
iex> Image.write(image, image_path, minimize_file_size: true,
...> png: [compress: 60, lossy: true],
...> jpg: [quality: 70],
...> webp: [quality: 5])
I need to add tests before publishing but you’re welcome to try it out by configuring image from GitHub.
Since this is now getting very specific I suggest followup questions/discussion on this topic move to image discussions on github.
hauleth
In most cases I prefer it over dealing with it on upload or whatever. Just slap some kind of cache in front of it to remove the need to duplicate work already done and you are good to go.
kip
@sodapopcan, :compression isn’t a valid option for .webp images. I checked the documentation and I can’t see a reference to it as an option so it’s just an example where different image types support different parameters for writing and therefore a generic writer is a bit tricky. Its why I added :minimise_file_size.
image returns an error on known but invalid options for a given image type so that there is no mysterious behaviour. Open to a discussion if that’s the right choice.
kip
Definitely agree, that’s why the :minimize_file_size option exists. But I messed the underlying options for .webp (now fixed). That’s the most generic “do the best you can” option to minimise the size of an image file.








