Generate gradient image with Python, NumPy
By treating images as NumPy array ndarray
, you can manipulate existing images or generate new images using NumPy functions.
This article introduces an example of generating a gradient image with NumPy functions.
np.linspace()
andnp.tile()
- Sample code to generate a gradient image
np.linspace()
and np.tile()
Although various methods are conceivable, in this article, create a gradient image by the following flow.
- 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 repeats 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))
Image.fromarray(np.uint8(array)).save('data/dst/gray_gradient_h.jpg', quality=95)
array = get_gradient_3d(512, 256, (0, 0, 0), (255, 255, 255), (False, False, False))
Image.fromarray(np.uint8(array)).save('data/dst/gray_gradient_v.jpg', quality=95)
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))
Image.fromarray(np.uint8(array)).save('data/dst/color_gradient.jpg', quality=95)