# I created an addon to use the colormaps from Matplotlib

You can get it here

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

## Original Question

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 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 at 9:21
• blog.michelanders.nl/2016/12/… Apr 22 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 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[0] >> 16),
to_blender_color(c[0] >> 8 & 0xff),
to_blender_color(c[0] & 0xff),
c[1]) 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[0]),
to_blender_color(c[1]),
to_blender_color(c[2]),
c[3]) 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[0]
height = img.size[1]

# 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[1] * width + target[0]) * 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 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 at 19:41
• Finally tested this today. Works brilliantly. Very nice my dude. Jun 1 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 at 8:21

# I created an addon to use the colormaps from Matplotlib

You can get it here

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