# Generate gradient image with Python, NumPy

Posted: 2019-05-14 / Tags: Python, NumPy, Image Processing

By treating images as NumPy array `ndarray`, you can manipulate existing images or generate new images using NumPy functions.

• `np.linspace()` and `np.tile()`
• Sample code to generate a gradient image

## np.linspace() and np.tile()

• Generate 1D arrays that increase or decrease at regular intervals with `numpy.linspace()`
• Arrange it in 2D with `numpy.tile()`

The gradient direction is vertical or horizontal only. It does not support diagonal or radial (round).

### np.linspace()

`np.linspace()` is a function that returns an equally spaced 1D array, given the start value `start`, the end value `stop`, and the number of samples `num`.

Unlike `range()` and `np.arange()`, `np.linspace()` is convenient because it calculates intervals (steps) automatically.

``````import numpy as np

print(np.linspace(0, 10, 3))
# [ 0.  5. 10.]

print(np.linspace(0, 10, 4))
# [ 0.          3.33333333  6.66666667 10.        ]

print(np.linspace(0, 10, 5))
# [ 0.   2.5  5.   7.5 10. ]
``````

It will handle properly if `start > stop`.

``````print(np.linspace(10, 0, 5))
# [10.   7.5  5.   2.5  0. ]
``````

See the following article for details of `np.arange()` and `np.linspace()`.

### np.tile()

`np.tile()` is a function that arranges the array vertically and horizontally.

It is useful for creating the array that repeat patterns.

Set the original array and the number of iterations. When arranging in two dimensions, the number of repetitions is `(the number of repetitions of rows (vertical), the number of repetitions of columns (horizontal))`.

``````import numpy as np

a = np.array([0, 1, 2, 3])

print(np.tile(a, 2))
# [0 1 2 3 0 1 2 3]

print(np.tile(a, (3, 2)))
# [[0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]]

print(np.tile(a, (2, 1)))
# [[0 1 2 3]
#  [0 1 2 3]]
``````

2D arrays can be handled in the same way.

``````a = np.array([[11, 12], [21, 22]])

print(np.tile(a, 2))
# [[11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (3, 2)))
# [[11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (2, 1)))
# [[11 12]
#  [21 22]
#  [11 12]
#  [21 22]]
``````

See the following article for more information on `np.tile()`.

## Sample code to generate a gradient image

Define a function that generates a 2D `ndarray` that increases or decreases at equal intervals in the vertical or horizontal direction. This `ndarray` corresponds to a monochrome (grayscale) gradient image.

The value changes in the horizontal direction when `is_horizontal` is `True`, and in the vertical direction when `False`. For vertical orientation, use `.T` to create a transposed matrix.

``````def get_gradient_2d(start, stop, width, height, is_horizontal):
if is_horizontal:
return np.tile(np.linspace(start, stop, width), (height, 1))
else:
return np.tile(np.linspace(start, stop, height), (width, 1)).T
``````

Expand this to three dimensions. Set `start`, `stop`, and `is_horizontal` for each color in a list, and create a gradient image for each channel with the function for 2D.

``````def get_gradient_3d(width, height, start_list, stop_list, is_horizontal_list):
result = np.zeros((height, width, len(start_list)), dtype=np.float)

for i, (start, stop, is_horizontal) in enumerate(zip(start_list, stop_list, is_horizontal_list)):
result[:, :, i] = get_gradient_2d(start, stop, width, height, is_horizontal)

return result
``````

An example of generating and saving a gradient image is as follows.

``````from PIL import Image

array = get_gradient_3d(512, 256, (0, 0, 0), (255, 255, 255), (True, True, True))
``````

``````array = get_gradient_3d(512, 256, (0, 0, 0), (255, 255, 255), (False, False, False))
``````

It is also possible to change the gradient direction for each RGB.

``````array = get_gradient_3d(512, 256, (0, 0, 192), (255, 255, 64), (True, False, False))
``````

Share