Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I convert RGB to Oklab? #1327

Open
test3211234 opened this issue Jan 26, 2025 · 1 comment
Open

How do I convert RGB to Oklab? #1327

test3211234 opened this issue Jan 26, 2025 · 1 comment

Comments

@test3211234
Copy link

test3211234 commented Jan 26, 2025

Question

I have a list of RGB tuples. I want to make it Oklab and make a linear gradient with it, then turn it into an RGB Pillow Image. Regular code for RGB looks like this. Please critique also, it's supposed to be as fast as it can be.

def create_linear_gradient(width, height, stops, direction):
    # stops is a list { percent, (r, g, b) }

    # Normalize the direction vector
    dx, dy = direction
    magnitude = (dx ** 2 + dy ** 2) ** 0.5
    dx /= magnitude
    dy /= magnitude

    # create coordinate grids
    x = np.linspace(0, 1, width)
    y = np.linspace(0, 1, height)
    xv, yv = np.meshgrid(x, y)

    # Compute the distance map and center it
    distance_map = (xv - 0.5) * dx + (yv - 0.5) * dy
    distance_map = distance_map - distance_map.min()
    distance_map = distance_map / distance_map.max()  # Normalize to [0, 1]

    # Sort and interpolate stops
    stops = sorted(stops, key=lambda stop: stop[1])
    stop_colors, stop_positions = zip(*stops)

    # Convert to arrays for interpolation
    stop_positions = np.array(stop_positions)
    stop_colors = np.array(stop_colors, dtype=np.float32)

    # Interpolate each color channel
    r_channel = np.interp(distance_map, stop_positions, stop_colors[:, 0])
    g_channel = np.interp(distance_map, stop_positions, stop_colors[:, 1])
    b_channel = np.interp(distance_map, stop_positions, stop_colors[:, 2])

    gradient = np.stack([r_channel, g_channel, b_channel], axis=-1).astype(np.uint8)

    return Image.fromarray(gradient)
@KelSolaar KelSolaar changed the title [DISCUSSION]: How do I convert RGB to Oklab? How do I convert RGB to Oklab? Jan 28, 2025
@KelSolaar
Copy link
Member

Typically, if you want a perceptually linear gradient, you would construct it within Oklab, idea would be to have your input values as RGB, e.g., start and end RGB triplets, convert them to Oklab and linear interpolate the Oklab correlates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants