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?
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),
(0xAADCE0, 1),
(0x72BCD5, 1),
(0x528FAD, 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
node = nodes.new(type='ShaderNodeValToRGB') # add color ramp node
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]
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
node = nodes.new(type='ShaderNodeValToRGB') # add color ramp node
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:
First the dimensions of the image are determined.
Then a reference to the specified material is created and a new node of the type ColorRamp
is created there.
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
color_ramp = material.node_tree.nodes.new("ShaderNodeValToRGB")
# 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.
You can get it here
ColorRamp
here, but wants to convert a color palette into aColorRamp
. The answers should therefore be different. $\endgroup$