Skip to content

Add affine, translate and shear transforms#202

Merged
kipcole9 merged 3 commits into
elixir-image:mainfrom
hlindset:feat/affine-translate-shear
Jun 30, 2026
Merged

Add affine, translate and shear transforms#202
kipcole9 merged 3 commits into
elixir-image:mainfrom
hlindset:feat/affine-translate-shear

Conversation

@hlindset

Copy link
Copy Markdown
Contributor

Adds an affine transform primitive, and two thin convenience wrappers:

  • Image.affine/3 / Image.affine!/3: applies an affine transform from a flat [a, b, c, d] matrix mapping (x, y) → (a*x + b*y, c*x + d*y), built on Vix.Vips.Operation.affine.
  • Image.translate/4 / Image.translate!/4: shifts content within a same-size canvas, clipping overflow.
  • Image.shear/4 / Image.shear!/4: horizontal/vertical shear.

They share the same options, validated by Image.Options.Affine: :idx/:idy/:odx/:ody (input/output displacements), :interpolate (:nearest, :bilinear (default), :bicubic, :lbb, :nohalo, :vsqbs), :background (sent through Image.Pixel.to_pixel/2, or :average), :extend_mode, and :output_area.

A fused affine avoids the per-pass resampling loss of chaining named ops.

Is this something you want in the library?

N.B. I grouped these functions under the "Distortion" docs category. Do you agree with that? Or should it be listed under "Operations"?

Out of scope discoveries made:

  • warp_perspective/straighten_perspective: :extend_mode is silently dropped, because Options.WarpPerspective passes it to mapim/3 under the key :extend_mode, but the op's option is :extend, so the value never takes effect. Even once that's fixed, mapim's extend (like affine's) is only applied to the thin antialiased fringe at the resampled edges, not the uncovered canvas (which is filled by :background), so the docs are inaccurate wrt. region fills
  • Image.rotate/3's background does not currently make use of Image.Pixel.to_pixel and does not support 4-element (RGBA) colors
  • Image.rotate/3 does not expose an interpolate option (supported by vix/libvips)

I'll submit PRs for those findings soon

@kipcole9 kipcole9 merged commit 6d02ff8 into elixir-image:main Jun 30, 2026
6 checks passed
@kipcole9

Copy link
Copy Markdown
Collaborator

Thank you again. Fabulous work and very thorough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants