# Efficient method for putting colormaps into color ramp?

Does anyone have an efficient method for importing color maps into a color ramp?

At the moment I have to get the hex codes for each step in a colorramp.  Anyone know a better idea?

• blender.stackexchange.com/questions/211601/… Apr 22, 2022 at 9:09
• @DuarteFarrajotaRamos I don't think he wants to use a color palette as a ColorRamp here, but wants to convert a color palette into a ColorRamp. The answers should therefore be different. Apr 22, 2022 at 9:21
• blog.michelanders.nl/2016/12/… Apr 22, 2022 at 9:25
• @TheJeran Take a closer look at my answer. With this solution you don't need to know HEX values or enter them manually somewhere. Apr 22, 2022 at 13:14 ## Run script to add ColorRamp to specify material

### Hex version

import bpy, math

material_name = "Material"  # choose your material_name here

color = [
(0xE76254, 1),  # red = 231, green = 98, blue = 84, alpha = 1, allow lower case
(0xEF8A47, 1),
(0xF7AA58, 1),
(0xFFD06F, 1),
(0xFFE6B7, 1),
(0x72BCD5, 1),
(0x376795, 1),
(0x1E466E, 1),
]

def to_blender_color(c):    # gamma correction
c = min(max(0, c), 255) / 255
return c / 12.92 if c < 0.04045 else math.pow((c + 0.055) / 1.055, 2.4)

blend_color = [(
to_blender_color(c >> 16),
to_blender_color(c >> 8 & 0xff),
to_blender_color(c & 0xff),
c) for c in color]
color_count = len(color)

for e in blend_color:
print(e)

mat     = bpy.data.materials[material_name] # choose material name here
tree    = mat.node_tree
nodes   = tree.nodes

ramp    = node.color_ramp
el      = ramp.elements

dis     = 1 / (color_count - 1)
x       = dis
for r in range(color_count - 2):
el.new(x)
x += dis

for i, e in enumerate(el):
e.color = blend_color[i]


### Dec Version

import bpy, math

material_name = "Material"  # choose your material_name here

color = [
(231, 98, 84, 1),
(247, 170, 88  1),
(..., 1),
]

def to_blender_color(c):    # gamma correction
c = min(max(0, c), 255) / 255
return c / 12.92 if c < 0.04045 else math.pow((c + 0.055) / 1.055, 2.4)

blend_color = [(
to_blender_color(c),
to_blender_color(c),
to_blender_color(c),
c) for c in color]
color_count = len(color)

for e in blend_color:
print(e)

mat     = bpy.data.materials[material_name] # choose material name here
tree    = mat.node_tree
nodes   = tree.nodes

ramp    = node.color_ramp
el      = ramp.elements

dis     = 1 / (color_count - 1)
x       = dis
for r in range(color_count - 2):
el.new(x)
x += dis

for i, e in enumerate(el):
e.color = blend_color[i]


Of course you have the possibility to use an image as color reference.

But if you really want to transfer your color values directly into a ColorRamp without knowing their HEX values, a small Python script will help you. It simply references an image (previously imported into Blender) by name, determines the color values of the pixels at certain positions and transfers them to a ColorRamp.

All you need for this example is that the color gradient runs horizontally and that you know the number of your colors and enter them into the script.

Furthermore, you have to enter the name of the previously imported image, as well as the name of your material.

In detail the following happens here:

1. First the dimensions of the image are determined.

2. Then a reference to the specified material is created and a new node of the type ColorRamp is created there.

3. In the loop, using the number of color values you specified, the pixel for reading the color is determined.

These color values are then transferred directly to the new positions of the ColorRamp created at the same time.

import bpy
from bpy import data as D

imageFile = "colorramp.png"
materialName = "Material"
colorCount = 10

# Get the reference to the specified image
img = D.images[imageFile]

# Determine height and width of the image
width = img.size
height = img.size

# Get the reference to the specified material
material = bpy.data.materials[materialName]

# Get the node collection of the material
nodes = material.node_tree.nodes

# Create a color ramp node

# Get a reference to the colorRamp node
cr=D.materials[materialName].node_tree.nodes["ColorRamp"].color_ramp

# Set interpolation between color stops to "CONSTANT"
cr.interpolation = "CONSTANT"

# Convert sRGB to linear RGB
def sRGB2linear(s):
if s <= 0.0404482362771082:
lin = s / 12.92
else:
lin = ((s + 0.055) / 1.055) ** 2.4
return lin

# Iterate through the colors
for x in range(colorCount):
# Define the position of the pixel we want to read out
target = [round(x * (width / colorCount) + width / colorCount/2), round(height / 2)]
# Determine the index of the pixel to be read out (#RGBA)
index = (target * width + target) * 4
if (x > 0 and x < colorCount -1):
# Add a new position to the ColorRamp
cr.elements.new(position = 1 / (colorCount - 1) * x)

# Read the color at the given index and set the color in the ColorRamp
cr.elements[x].color=(
sRGB2linear(img.pixels[index]), # R
sRGB2linear(img.pixels[index + 1]), #G
sRGB2linear(img.pixels[index + 2]), #B
1, #A
)



UPDATE: Added conversion from sRGB to linear.

• This looks pretty interesting. I will let you know how it works for me when I try it. Will probably be in two weeks when I return to that task. Apr 22, 2022 at 18:53
• @TheJeran I assume that it even fits perfectly for you ;-) You asked for a better and more efficient method, and it doesn't really get much easier than determining the color values automatically. Apr 22, 2022 at 19:41
• Finally tested this today. Works brilliantly. Very nice my dude. Jun 1, 2022 at 8:12
• @TheJeran ...Thanks for testing! I'm just wondering why you then got happy with an answer where you have to enter the values again by hand. ;-) Jun 1, 2022 at 8:21

# I created an addon to use the colormaps from Matplotlib You can get it here

https://github.com/TheJeran/Blender-Colormaps/