Most image editing software has gradient map functions. Gradient maps take the brightness of a given pixel and apply a gradient of colors according to brightness. Photoshop and other software have ways to automate this, but they can't do exactly what I want, so I thought Python might do the trick. Unfortunately I'm having a very hard time understanding or applying any of the results that come up when I search for gradient maps or color maps with Python.
All the potential solution threads I found used numpy or matplotlib which have lots of mathy lines that go right over my head... I would love some help with this. Initially I had something going with Processing, but I found the task of exporting tons of images with Processing to be weird and hacky. Plus I like Python, and want to learn how to edit and generate art with it.
This is what I'm working with right now.
from PIL import Image
myPalette = ['#1A1423', '#684756', '#AB8476']
def colorMap(pixel, palette):
# Calculate the brightness of pixel
R, G, B = pixel
brightness = sum([R, G, B])/3
# Map gradient of colors to brightness
# ???...
return mappedColor
img = Image.open('image_input.png')
pixels = img.load()
for x in range(img.size[0]):
for y in range(img.size[1]):
pixel = img.getpixel((x, y))
pixels[x, y] = colorMap(pixel, myPalette)
img.save('image_output.png')
Loading, calculating brightness, and saving are easy. I just have no idea how to apply a gradient of my palette to the pixel.
You can do that quite easily with ImageMagick or with PIL/Numpy/OpenCV.
The first thing is to get hold of the colormap - the vertical bar down the right side of your image. I don't have or know Clip Studio, so maybe it will let you export the colormap, or create a greyscale gradient and apply the colormap to it, then save the result as a PNG. In my case, I loaded your image into Photoshop, cut out the gradient and rotated it to make an image exactly 256-pixels wide by 1-pixel high. Enlarged, that looks like this:
colourmap.png
I also cropped your swirl thing off the left side of your image - please post images separately in future.
swirl.png
Now for applying it. First, just with ImageMagick in Terminal. I loaded your swirl image and separated it into its constituent RGB channels then averaged the channels and applied the colourmap, also known as CLUT or "Colour Lookup Table":
magick swirl.png -channel RGB -separate -evaluate-sequence mean colourmap.png -clut result.png
Next, same thing with PIL/Numpy:
#!/usr/bin/env python3
import numpy as np
from PIL import Image
# Load image, make into Numpy array and average RGB channels
im = Image.open('swirl.png').convert('RGB')
na = np.array(im)
grey = np.mean(na, axis=2).astype(np.uint8)
Image.fromarray(grey).save('DEBUG-grey.png') # DEBUG only
# Load colourmap
cmap = Image.open('colourmap.png').convert('RGB')
# cmap must be resized to have a width of 256
# since grey's scaled from 0-255, so np.take will select from indices 0-255 only
cmap = cmap.resize((256, 1))
# Make output image same height and width as grey image, but 3-channel RGB
result = np.zeros((*grey.shape,3), dtype=np.uint8)
# Take entries from RGB colourmap according to greyscale values in image
np.take(cmap.getdata(), grey, axis=0, out=result)
# Save result
Image.fromarray(result).save('result.png')
You can also generate piece-wise linear colormaps like this:
magick -size 160x1 gradient:navy-"rgb(220,110,110)" \
-size 60x1 gradient:"rgb(220,110,110)"-yellow \
-size 35x1 gradient:yellow-white \
+append colourmap.png
That makes three segments each with a linear gradient:
then appends them together.
If you make all the segments of the colour map the same length, you will get a different interpretation:
magick -size 85x1 \
gradient:navy-"rgb(220,110,110)" \
gradient:"rgb(220,110,110)"-yellow \
gradient:yellow-white +append -resize 256x1\! colourmap.png
That leads to this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With