diff --git a/lib/image.ex b/lib/image.ex index 6364836..78a9490 100644 --- a/lib/image.ex +++ b/lib/image.ex @@ -917,6 +917,12 @@ defmodule Image do "[" <> Enum.map_join(options, ",", &loader_option/1) <> "]" end + # Numeric arrays (e.g. `background=0 128 0`) are space separated in a + # filename suffix string. + defp loader_option({key, [number | _rest] = value}) when is_number(number) do + "#{key}=" <> Enum.map_join(value, " ", &to_string/1) + end + # Flag-valued options are passed to libvips as a list of flag atoms. # In a filename suffix string flags are written by name joined with `:`, # e.g. `keep=VIPS_FOREIGN_KEEP_EXIF:VIPS_FOREIGN_KEEP_XMP`. diff --git a/test/image_write_background_test.exs b/test/image_write_background_test.exs index e0c9af9..5f03f30 100644 --- a/test/image_write_background_test.exs +++ b/test/image_write_background_test.exs @@ -54,5 +54,25 @@ defmodule Image.Write.Background.Test do assert message =~ "Invalid background color :not_a_real_color" end + + test "the background survives a :memory write", %{rgba: rgba} do + # Regression: the suffix option string joined numeric arrays with ":" + # (".jpg[background=0:128:0]"), which libvips silently drops. Arrays + # must be space separated. + {:ok, binary} = Image.write(rgba, :memory, suffix: ".jpg", background: :green) + pixel = Image.get_pixel!(Image.open!(binary), 4, 4) + + assert close_to?(pixel, [0, 128, 0]) + end + + test "the background survives a stream write", %{rgba: rgba, tmp_dir: tmp_dir} do + path = Temp.path!(suffix: ".jpg", basedir: tmp_dir) + stream = File.stream!(path, 2048) + + {:ok, _} = Image.write(rgba, stream, background: :green) + pixel = Image.get_pixel!(Image.open!(path), 4, 4) + + assert close_to?(pixel, [0, 128, 0]) + end end end