From 9bb29341b266496274cd85cf29d16c94c53ce62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 30 Jun 2026 02:10:06 +0200 Subject: [PATCH] Fix warp_perspective :extend_mode silent no-op and correct its docs --- lib/image.ex | 86 ++++++++++----------------- lib/image/options/warp_perspective.ex | 9 ++- 2 files changed, 37 insertions(+), 58 deletions(-) diff --git a/lib/image.ex b/lib/image.ex index 8d0d87b..15df562 100644 --- a/lib/image.ex +++ b/lib/image.ex @@ -11015,20 +11015,21 @@ defmodule Image do in which case the background will be the average color of the base image. See also `Color.new/2` from the Color library. - * `:extend_mode` determines how any additional pixels - are generated. The values are: - - * `:black` (the default) meaning the generated pixels are - black. - * `:white` meaning the generated pixels are white. - * `:copy` means the generated pixels take the value of the - nearest edge pixel of the base image. - * `:repeat` means the generated pixels are tiles from the - base image. - * `:mirror` means the generated pixels are a reflected tiles of - the base image. - * `:background` means the generated pixels are the background - color setin `options`. + * `:extend_mode` controls how the interpolator synthesises the + thin band of pixels just beyond the source edge when resampling + the warped content boundary. It is visible only as a one-pixel + fringe along the content edge. It does *not* fill the blank + canvas left uncovered by the transformation — that area is + always filled with `:background`. The values are: + + * `:background` (the default) means the synthesised pixels use + the `:background` color. + * `:black` means the synthesised pixels are black. + * `:white` means the synthesised pixels are white. + * `:copy` means the synthesised pixels copy the nearest edge + pixel of the base image. + * `:repeat` means the base image is tiled. + * `:mirror` means the base image is reflected. ### Notes @@ -11093,20 +11094,11 @@ defmodule Image do also be set to `:average` in which case the background will be the average color of the base image. See also `Color.new/2` from the Color library. - * `:extend_mode` determines how any additional pixels - are generated. The values are: - - * `:black` (the default) meaning the generated pixels are - black. - * `:white` meaning the generated pixels are white. - * `:copy` means the generated pixels take the value of the - nearest edge pixel of the base image. - * `:repeat` means the generated pixels are tiles from the - base image. - * `:mirror` means the generated pixels are a reflected tiles of - the base image. - * `:background` means the generated pixels are the background - color setin `options`. + * `:extend_mode` controls how pixels just beyond the source edge + are synthesised during interpolation. It is visible only as a + one-pixel fringe along the content edge; it does not fill the + blank canvas left uncovered by the transformation, which is + always filled by `:background`. See `Image.warp_perspective/4`. ### Returns @@ -11166,20 +11158,11 @@ defmodule Image do also be set to `:average` in which case the background will be the average color of the base image. See also `Color.new/2` from the Color library. - * `:extend_mode` determines how any additional pixels - are generated. The values are: - - * `:black` (the default) meaning the generated pixels are - black. - * `:white` meaning the generated pixels are white. - * `:copy` means the generated pixels take the value of the - nearest edge pixel of the base image. - * `:repeat` means the generated pixels are tiles from the - base image. - * `:mirror` means the generated pixels are a reflected tiles of - the base image. - * `:background` means the generated pixels are the background - color setin `options`. + * `:extend_mode` controls how pixels just beyond the source edge + are synthesised during interpolation. It is visible only as a + one-pixel fringe along the content edge; it does not fill the + blank canvas left uncovered by the transformation, which is + always filled by `:background`. See `Image.warp_perspective/4`. ### Returns @@ -11249,20 +11232,11 @@ defmodule Image do also be set to `:average` in which case the background will be the average color of the base image. See also `Color.new/2` from the Color library. - * `:extend_mode` determines how any additional pixels - are generated. The values are: - - * `:black` (the default) meaning the generated pixels are - black. - * `:white` meaning the generated pixels are white. - * `:copy` means the generated pixels take the value of the - nearest edge pixel of the base image. - * `:repeat` means the generated pixels are tiles from the - base image. - * `:mirror` means the generated pixels are a reflected tiles of - the base image. - * `:background` means the generated pixels are the background - color setin `options`. + * `:extend_mode` controls how pixels just beyond the source edge + are synthesised during interpolation. It is visible only as a + one-pixel fringe along the content edge; it does not fill the + blank canvas left uncovered by the transformation, which is + always filled by `:background`. See `Image.warp_perspective/4`. ### Returns diff --git a/lib/image/options/warp_perspective.ex b/lib/image/options/warp_perspective.ex index eed8d9b..892f44f 100644 --- a/lib/image/options/warp_perspective.ex +++ b/lib/image/options/warp_perspective.ex @@ -76,10 +76,15 @@ defmodule Image.Options.WarpPerspective do end end + # The public option is `:extend_mode`, renamed internally to `:extend` for `libvips` defp validate_option({:extend_mode, extend}, _image, options) do case Image.ExtendMode.validate_extend(extend) do {:ok, extend_mode} -> - options = Keyword.put(options, :extend_mode, extend_mode) + options = + options + |> Keyword.delete(:extend_mode) + |> Keyword.put(:extend, extend_mode) + {:cont, options} {:error, reason} -> @@ -97,7 +102,7 @@ defmodule Image.Options.WarpPerspective do defp default_options do [ - extend_mode: :black, + extend_mode: :background, background: :black ] end