# `Image.Math`
[🔗](https://github.com/elixir-image/image/blob/v0.65.0/lib/image/math.ex#L1)

Implements math operators for images,
delegating to the `Kernel` functions in the
cases where the parameters do not include
`t:Vix.Vips.Image.t/0`.

To override the standard operations in a
function or module, add `use Image.Math`.

To maximise readability and clarity it
is recommended that `use Image.Math` be added
to only those functions that require it.

### Example

    defmodule MyModule do
      # Not recommended
      use Image.Math

      def my_function(%Vix.Vips.Image{} = image) do
        # Recommended
        use Image.Math

        # Increase the all bands by 20%
        brigher = image * 1.2

        # Or adjust only green by 20%
        bright_green = image * [1, 1.2, 1]
      end
    end

# `&&&`

Matrix bitwise 'and' of
two images.

# `**`

Matrix exponent of two images or
one image and a constant or vector.

Delegates to `Kernel.**/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `*`

Matrix multiplation of two images or
one image and a constant or vector.

Delegates to `Kernel.*/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `+`

Matrix addition of two images or
one image and a constant or vector.

Delegates to `Kernel.+/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `-`

Matrix unary minues of an
image or a number.

# `-`

Matrix subtraction of two images or
one image and a constant or vector.

Delegates to `Kernel.-/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `/`

Matrix division of two images or
one image and a constant or vector.

Delegates to `Kernel.//2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `!=`

Matrix inequality of two images or
one image and a constant or vector.

Delegates to `Kernel.!=/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `<`

Matrix less than of two images or
one image and a constant or vector.

Delegates to `Kernel.</2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `<<<`

Matrix bitwise 'left shift' of
two images.

# `<=`

Matrix less than or equal of two images or
one image and a constant or vector.

Delegates to `Kernel.<=/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `==`

Matrix equality of two images or
one image and a constant or vector.

Delegates to `Kernel.==/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `>`

Matrix greater than of two images or
one image and a constant or vector.

Delegates to `Kernel.>/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `>=`

Matrix greater than or equal of two images or
one image and a constant or vector.

Delegates to `Kernel.>=/2` if none of
the parameters is a `t:Vix.Vips.Image.t/0`.

# `>>>`

Matrix bitwise 'right shift' of
two images.

# `abs`

```elixir
@spec abs(Vix.Vips.Image.t()) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec abs(number()) :: {:ok, number()}
```

# `abs!`

```elixir
@spec abs!(Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
```

# `add`

```elixir
@spec add(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec add(Vix.Vips.Image.t(), number()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec add(Vix.Vips.Image.t(), [number(), ...]) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec add(number(), number()) :: {:ok, number()}
```

# `add!`

```elixir
@spec add!(Vix.Vips.Image.t(), Image.pixel() | number()) ::
  Vix.Vips.Image.t() | no_return()
@spec add!(Image.pixel() | number(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
@spec add!(number(), number()) :: number() | no_return()
```

# `boolean_and`

```elixir
@spec boolean_and(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `boolean_and!`

```elixir
@spec boolean_and!(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
```

# `boolean_lshift`

```elixir
@spec boolean_lshift(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `boolean_lshift!`

```elixir
@spec boolean_lshift!(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
```

# `boolean_or`

```elixir
@spec boolean_or(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `boolean_or!`

```elixir
@spec boolean_or!(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
```

# `boolean_rshift`

```elixir
@spec boolean_rshift(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `boolean_rshift!`

```elixir
@spec boolean_rshift!(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
```

# `boolean_xor`

```elixir
@spec boolean_xor(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `boolean_xor!`

```elixir
@spec boolean_xor!(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
```

# `bottom_n`

```elixir
@spec bottom_n(image :: Vix.Vips.Image.t(), n :: non_neg_integer()) ::
  {minimim :: float(), x_max :: non_neg_integer(), y_max :: non_neg_integer(),
   max_coordinates :: [Image.point(), ...]}
```

Return the bottom `n` image minima.

The function returns the coordinates of`:n`
smallest values of the image.

### Arguments

* `image` is any `t:Vix.Vips.Image.t/0`.

* `n` is the number of minima to find. The
  default is `10`. Minima in this case means the
  smallest `n` values; They may not be equal to the
  minimum.

### Returns

* `{minimum, x_min, y_min, [{x, y}, ...])`

# `cos`

```elixir
@spec cos(Vix.Vips.Image.t()) :: {:ok, Vix.Vips.Image.t()}
@spec cos(number()) :: {:ok, number()}
```

# `cos!`

```elixir
@spec cos!(Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
```

# `divide`

```elixir
@spec divide(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec divide(Vix.Vips.Image.t(), number()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec divide(number(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec divide(Vix.Vips.Image.t(), [number()]) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec divide(number(), number()) :: {:ok, number()}
```

# `divide!`

```elixir
@spec divide!(Vix.Vips.Image.t(), Image.pixel()) :: Vix.Vips.Image.t() | no_return()
@spec divide!(Image.pixel(), Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
@spec divide!(number(), number()) :: number() | no_return()
```

# `equal`

```elixir
@spec equal(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec equal(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `equal!`

```elixir
@spec equal!(Vix.Vips.Image.t(), Image.pixel()) :: Vix.Vips.Image.t() | no_return()
@spec equal!(number(), number()) :: number() | no_return()
```

# `exp`

```elixir
@spec exp(Vix.Vips.Image.t()) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `exp!`

```elixir
@spec exp!(Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
```

# `greater_than`

```elixir
@spec greater_than(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec greater_than(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `greater_than!`

```elixir
@spec greater_than!(Vix.Vips.Image.t(), Vix.Vips.Image.t() | Image.pixel()) ::
  Vix.Vips.Image.t() | no_return()
@spec greater_than!(number(), number()) :: number() | no_return()
```

# `greater_than_or_equal`

```elixir
@spec greater_than_or_equal(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec greater_than_or_equal(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `greater_than_or_equal!`

```elixir
@spec greater_than_or_equal!(Vix.Vips.Image.t(), Image.pixel()) ::
  Vix.Vips.Image.t() | no_return()
@spec greater_than_or_equal!(number(), number()) :: number() | no_return()
```

# `is_pixel`
*macro* 

Guards if a given value might be reasonably interpreted
as a pixel.

# `less_than`

```elixir
@spec less_than(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec less_than(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `less_than!`

```elixir
@spec less_than!(Vix.Vips.Image.t(), Vix.Vips.Image.t() | Image.pixel()) ::
  Vix.Vips.Image.t() | no_return()
@spec less_than!(number(), number()) :: number() | no_return()
```

# `less_than_or_equal`

```elixir
@spec less_than_or_equal(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec less_than_or_equal(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `less_than_or_equal!`

```elixir
@spec less_than_or_equal!(Vix.Vips.Image.t(), Vix.Vips.Image.t() | Image.pixel()) ::
  Vix.Vips.Image.t() | no_return()
@spec less_than_or_equal!(number(), number()) :: number() | no_return()
```

# `max`

```elixir
@spec max(Vix.Vips.Image.t()) :: {:ok, float()} | {:error, Image.error()}
```

# `max!`

```elixir
@spec max!(Vix.Vips.Image.t()) :: float() | no_return()
```

# `maxpos`

```elixir
@spec maxpos(image :: Vix.Vips.Image.t(), n :: non_neg_integer()) ::
  {maximum :: number(), max_coordinates :: [Image.point(), ...],
   maybe_overflow :: :maybe_overflow | nil}
```

Return the image maxima.

This function retrieves the coordinates of the `n`
largest values then then filters them to return only
those coordinates that have the maximum value.

### Arguments

* `image` is any `t:Vix.Vips.Image.t/0`.

* `n` is the number of maxima to find. The
  default is `10`. Maxima in this case means
  those values that exactly match the maximum
  value.

### Returns

* `{maximum, [{x, y}, ...], maybe_overflow)`.  If
  `maybe_overflow` is set to `:maybe_overflow` its an indication
  that the number of coordinates is the same as the requested `n`.
  Therefore it is possible - maybe even likely - that there are other
  coordinates that have the maximum value but have not been returned.

### Example

  This example draws a red image with a single green pixel. We then
  look for all the coordinates that have a green pixel.

    iex> {:ok, image} =
    iex>   Image.new!(5, 5, color: :red)
    iex>   |> Image.mutate(fn i -> Image.Draw.point!(i, 2, 2, color: [0,255,0]) end)
    iex> image
    iex> |> Image.Math.==([0, 255, 0])
    iex> |> Image.band_and!()
    iex> |> Image.Math.maxpos()
    {255, [{2, 2}], nil}

    # Since all pixels are red and we want
    # the coordinates of all the red pixels
    # we have an overlow: We retrieve only 3
    # maxima and they are all red. Perhaps
    # the red of the image pixels are also red?
    # Yes - they are!
    iex> Image.new!(2, 2, color: :red)
    iex> |> Image.Math.==([255, 0, 0])
    iex> |> Image.band_and!()
    iex> |> Image.Math.maxpos(3)
    {255, [{0, 1}, {1, 0}, {0, 0}], :maybe_overflow}

# `min`

```elixir
@spec min(Vix.Vips.Image.t()) :: {:ok, float()} | {:error, Image.error()}
```

# `min!`

```elixir
@spec min!(Vix.Vips.Image.t()) :: float() | no_return()
```

# `minpos`

```elixir
@spec minpos(image :: Vix.Vips.Image.t(), n :: non_neg_integer()) ::
  {maximum :: number(), max_coordinates :: [Image.point(), ...],
   maybe_overflow :: :maybe_overflow | nil}
```

Return the image minima.

This function retrieves the coordinates of the `n`
smallest values then then filters them to return only
those coordinates that have the minimum value.

### Arguments

* `image` is any `t:Vix.Vips.Image.t/0`.

* `n` is the number of minima to find. The
  default is `10`. Minima in this case means
  those values that exactly match the minimum
  value.

### Returns

* `{minimum, [{x, y}, ...], maybe_overflow)`.  If
  `maybe_overflow` is set to `:maybe_overflow` its an indication
  that the number of coordinates is the same as the requested `n`.
  Therefore it is possible - maybe even likely - that there are other
  coordinates that have the minimum value but have not been returned.

# `multiply`

```elixir
@spec multiply(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec multiply(Vix.Vips.Image.t(), number()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec multiply(number(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec multiply(Vix.Vips.Image.t(), list()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec multiply(number(), number()) :: {:ok, number()}
```

# `multiply!`

```elixir
@spec multiply!(Vix.Vips.Image.t(), Image.pixel() | number()) ::
  Vix.Vips.Image.t() | no_return()
@spec multiply!(Image.pixel() | number(), Vix.Vips.Image.t()) ::
  Vix.Vips.Image.t() | no_return()
@spec multiply!(number(), number()) :: number() | no_return()
```

# `not_equal`

```elixir
@spec not_equal(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec not_equal(Vix.Vips.Image.t(), Image.pixel()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
```

# `not_equal!`

```elixir
@spec not_equal!(Vix.Vips.Image.t(), Image.pixel()) ::
  Vix.Vips.Image.t() | no_return()
@spec not_equal!(number(), number()) :: number() | no_return()
```

# `pow`

```elixir
@spec pow(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec pow(Vix.Vips.Image.t(), number()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec pow(number(), number()) :: {:ok, number()}
```

# `pow!`

```elixir
@spec pow!(Vix.Vips.Image.t(), number()) :: Vix.Vips.Image.t() | no_return()
@spec pow!(number(), number()) :: number() | no_return()
```

# `sin`

```elixir
@spec sin(Vix.Vips.Image.t()) :: {:ok, Vix.Vips.Image.t()}
@spec sin(number()) :: {:ok, number()}
```

# `sin!`

```elixir
@spec sin!(Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
```

# `subtract`

```elixir
@spec subtract(Vix.Vips.Image.t(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec subtract(Vix.Vips.Image.t(), number()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec subtract(Vix.Vips.Image.t(), [number()]) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec subtract(number(), Vix.Vips.Image.t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}
@spec subtract(number(), number()) :: {:ok, number()}
```

# `subtract!`

```elixir
@spec subtract!(Vix.Vips.Image.t(), Image.pixel()) :: Vix.Vips.Image.t() | no_return()
@spec subtract!(Image.pixel(), Vix.Vips.Image.t()) :: Vix.Vips.Image.t() | no_return()
@spec subtract!(number(), number()) :: number() | no_return()
```

# `top_n`

```elixir
@spec top_n(image :: Vix.Vips.Image.t(), n :: non_neg_integer()) ::
  {maximum :: float(), x_max :: non_neg_integer(), y_max :: non_neg_integer(),
   max_coordinates :: [Image.point(), ...]}
```

Return the top `n` image maxima.

The function returns the coordinates of`:n`
largest values of the image.

### Arguments

* `image` is any `t:Vix.Vips.Image.t/0`.

* `n` is the number of maxima to find. The
  default is `10`. Maxima in this case means the
  largest `n` values; They may not be equal to the
  maximum.

### Returns

* `{maximum, x_max, y_max, [{x, y}, ...])`

# `|||`

Matrix bitwise 'or' of
two images.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
