diff --git a/huepaper.nim b/huepaper.nim new file mode 100644 index 0000000..d12063f --- /dev/null +++ b/huepaper.nim @@ -0,0 +1,7 @@ +import huepaperlib + +let bc = getBaseColor() +let cols = createColors(bc, hueMax = 0.5) +let img = createBaseHuepaper(cols, 1920, 1080) + +img.saveHuepaper("test.png") diff --git a/huepaperlib.nim b/huepaperlib.nim new file mode 100644 index 0000000..6c303a6 --- /dev/null +++ b/huepaperlib.nim @@ -0,0 +1,79 @@ +import chroma, pixie, random + + +proc getBaseColor*(colorString: string = "", satMin: float = 0.2, + satMax: float = 1.0, lumMin: float = 0.2, lumMax: float = 0.9): ColorHSL = + ## Get base HSL color for a huepaper by `colorString`. + + # If no color string is given, create a random color + if colorString == "": + randomize() + let + hue = 360 * rand(1.0) + sat = 100 * (satMin + rand(satMax - satMin)) + lum = 100 * (lumMin + rand(lumMax - lumMin)) + result = hsl(hue, sat, lum) + + # Else try to parse string + else: + try: + result = colorString.parseHtmlColor.hsl + except InvalidColor: + result = ("#" & colorString).parseHtmlColor.hsl + + +proc createColors*(baseColor: ColorHSL, hueMax: float = 0.1, + satMin: float = 0.2, satMax: float = 1.0, lumMin: float = 0.2, + lumMax: float = 0.9): array[4, ColorRGB] = + ## Create four RGB corner colors for a huepaper based on a HSL `baseColor`. + randomize() + + let + maxSatDiff = 0.1 + maxLumDiff = 0.1 + + # Create four random colors similar to the given base_color + for i in 0 .. 3: + var + tmpHue = baseColor.h + 360 * (-hueMax / 2.0 + rand(hueMax)) + tmpSat = baseColor.s + 100 * (-maxSatDiff + rand(2.0 * maxSatDiff)) + tmpLum = baseColor.l + 100 * (-maxLumDiff + rand(2.0 * maxLumDiff)) + + # Correct hue + if tmpHue > 360.0: + tmpHue -= 360.0 + + # Clip saturation and luminance + tmpSat = min(100 * satMax, max(100 * satMin, tmpSat)) + tmpLum = min(100 * lumMax, max(100 * lumMin, tmpLum)) + + result[i] = hsl(tmpHue, tmpSat, tmpLum).color.rgb + + +func blend(c1, c2: ColorRGB, factor: float): ColorRGB = + ## Blends color `c1` to color `c2` with a `factor` from 0 to 1. + result.r = (uint8)((1.0 - factor) * (float)c1.r) + (uint8)(factor * (float)c2.r) + result.g = (uint8)((1.0 - factor) * (float)c1.g) + (uint8)(factor * (float)c2.g) + result.b = (uint8)((1.0 - factor) * (float)c1.b) + (uint8)(factor * (float)c2.b) + + +func createBaseHuepaper*(colors: array[4, ColorRGB], width, + height: int): Image = + ## Creates a base huepaper with given `width` and `height`. + ## The `colors` are placed in clockwise order, beginning from top left. + result = newImage(width, height) + + var + leftColor: ColorRGB + rightColor: ColorRGB + + for y in 0 ..< height: + leftColor = colors[0].blend(colors[3], y / (height - 1)) + rightColor = colors[1].blend(colors[2], y / (height - 1)) + for x in 0 ..< width: + result[x, y] = leftColor.blend(rightColor, x / (width - 1)) + + +proc saveHuepaper*(huepaper: Image, filePath: string) = + ## Save `huepaper` at `filePath`. + huepaper.writeFile(filePath)