@ -43,42 +43,48 @@ func ToRGB(s string) color.RGBA {
r := binary.LittleEndian.Uint64(sum[:8])
r := binary.LittleEndian.Uint64(sum[:8])
g := binary.LittleEndian.Uint64(sum[8:16])
g := binary.LittleEndian.Uint64(sum[8:16])
b := binary.LittleEndian.Uint64(sum[12:])
b := binary.LittleEndian.Uint64(sum[12:])
rgb.R = uint8(Interpolat eUint64(r, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.R = uint8(Scal eUint64(r, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.G = uint8(Interpolat eUint64(g, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.G = uint8(Scal eUint64(g, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.B = uint8(Interpolat eUint64(b, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.B = uint8(Scal eUint64(b, 0, uint64(math.Pow(2, 56)), 0, 64384))
rgb.A = uint8(255)
rgb.A = uint8(255)
return rgb
return rgb
}
}
```
```
`ToRGBA` functions almost identically, with a few small changes. Instead of 7 byte chunks, we use 5 byte chunks and adjust the ` Interpolat e` call accordingly for the 40 bit chunks.
`ToRGBA` functions almost identically, with a few small changes. Instead of 7 byte chunks, we use 5 byte chunks and adjust the ` Scal e` call accordingly for the 40 bit chunks.
```go
```go
func ToRGBA(s string) color.RGBA {
func ToRGBA(s string) color.RGBA {
// ...
// ...
a := binary.LittleEndian.Uint64(sum[15:])
// We use Uint32 here because the chunks are smaller and the Uint64 function panics if the input []byte is too short.
a := binary.LittleEndian.Uint32(sum[15:])
// ...
// ...
rgba.A = uint8(Interpolat eUint64(a, 0, uint64(math.Pow(2, 40)), 0, 64384))
rgba.A = uint8(Scal eUint64(a, 0, uint64(math.Pow(2, 40)), 0, 64384))
// ...
// ...
return rgb
return rgb
}
}
```
```
### Interpolation
### Scaling
- Not sure if interpolation is the right technical term
The final bit of magic we need is a way to scale these 64 bit integers down to between 0 and 255 to represent the RGB ( and sometimes A ) values that make up the `image.Color` . Enter the `Scale` function:
- Using generics
```go
```go
func Interpolate[T constraints.Uns igned](f, inputMin, inputMax, outputMin, outputMax T) T {
func Scale[T constraints.Unsigned | constraints.Float | constraints.S igned](f, inputMin, inputMax, outputMin, outputMax T) T {
return (f-(inputMin))*(outputMax-outputMin)/(inputMax-inputMin) + outputMin
return (f-(inputMin))*(outputMax-outputMin)/(inputMax-inputMin) + outputMin
}
}
var ScaleUint64 = Scale[uint64]
```
```
This does a bit of relatively straightforward math to smoothly scale the input into the desired range. Not a lot to say about it, it's just math and I don't know much about where it came from. I've had this floating around in various repos for years and I don't have any notes on where I found it.
## The Results
## The Results
Below is a sample of "lorem ipsum" with each word colored using this algorithm.
Below is a sample of "lorem ipsum" with each word colored using this algorithm.
< p > < span style = "color:#FD9FAB;" > Lorem< / span > < span style = "color:#D35EC5;" > ipsum< / span > < span style = "color:#45EEDD;" > dolor< / span > < span style = "color:#3A2FE8;" > sit< / span > < span style = "color:#04B55A;" > amet< / span > , < span style = "color:#883581;" > consectetur< / span > < span style = "color:#31CA93;" > adipiscing< / span > < span style = "color:#99461B;" > elit< / span > , < span style = "color:#000AF1;" > sed< / span > < span style = "color:#899099;" > do< / span > < span style = "color:#7B05AB;" > eiusmod< / span > < span style = "color:#F0B186;" > tempor< / span > < span style = "color:#3D1519;" > incididunt< / span > < span style = "color:#93B1CD;" > ut< / span > < span style = "color:#8333C5;" > labore< / span > < span style = "color:#846002;" > et< / span > < span style = "color:#81BB0B;" > dolore< / span > < span style = "color:#E3DDD1;" > magna< / span > < span style = "color:#877C09;" > aliqua< / span > . < span style = "color:#CB6967;" > Ut< / span > < span style = "color:#B38347;" > enim< / span > < span style = "color:#4B8A53;" > ad< / span > < span style = "color:#078AC6;" > minim< / span > < span style = "color:#D2F7E3;" > veniam< / span > , < span style = "color:#6BD5A2;" > quis< / span > < span style = "color:#2B37D2;" > nostrud< / span > < span style = "color:#C592D6;" > exercitation< / span > < span style = "color:#0EB9D1;" > ullamco< / span > < span style = "color:#9BC026;" > laboris< / span > < span style = "color:#872CC2;" > nisi< / span > < span style = "color:#93B1CD;" > ut< / span > < span style = "color:#7DB82B;" > aliquip< / span > < span style = "color:#1CED95;" > ex< / span > < span style = "color:#C0504C;" > ea< / span > < span style = "color:#5DA8B5;" > commodo< / span > < span style = "color:#B762A6;" > consequat< / span > . < span style = "color:#2FCB06;" > Duis< / span > < span style = "color:#EADF81;" > aute< / span > < span style = "color:#0602B8;" > irure< / span > < span style = "color:#45EEDD;" > dolor< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#8B2DEF;" > reprehenderit< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#790B62;" > voluptate< / span > < span style = "color:#7486E8;" > velit< / span > < span style = "color:#33E7F2;" > esse< / span > < span style = "color:#DE099F;" > cillum< / span > < span style = "color:#81BB0B;" > dolore< / span > < span style = "color:#C514CD;" > eu< / span > < span style = "color:#B4B15A;" > fugiat< / span > < span style = "color:#93AA9C;" > nulla< / span > < span style = "color:#83967C;" > pariatur< / span > . < span style = "color:#EDD318;" > Excepteur< / span > < span style = "color:#580A2A;" > sint< / span > < span style = "color:#7DC184;" > occaecat< / span > < span style = "color:#BCEEAB;" > cupidatat< / span > < span style = "color:#EA0503;" > non< / span > < span style = "color:#0AC6DC;" > proident< / span > , < span style = "color:#90C0A3;" > sunt< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#0C0B4B;" > culpa< / span > < span style = "color:#B0E1D5;" > qui< / span > < span style = "color:#F8F0B6;" > officia< / span > < span style = "color:#FFF0B6;" > deserunt< / span > < span style = "color:#115AE8;" > mollit< / span > < span style = "color:#6EC31F;" > anim< / span > < span style = "color:#10B00E;" > id< / span > < span style = "color:#8ADFA4;" > est< / span > < span style = "color:#7EBB61;" > laborum< / span > . < / p >
< p > < span style = "color:#FD9FAB;" > Lorem< / span > < span style = "color:#D35EC5;" > ipsum< / span > < span style = "color:#45EEDD;" > dolor< / span > < span style = "color:#3A2FE8;" > sit< / span > < span style = "color:#04B55A;" > amet< / span > , < span style = "color:#883581;" > consectetur< / span > < span style = "color:#31CA93;" > adipiscing< / span > < span style = "color:#99461B;" > elit< / span > , < span style = "color:#000AF1;" > sed< / span > < span style = "color:#899099;" > do< / span > < span style = "color:#7B05AB;" > eiusmod< / span > < span style = "color:#F0B186;" > tempor< / span > < span style = "color:#3D1519;" > incididunt< / span > < span style = "color:#93B1CD;" > ut< / span > < span style = "color:#8333C5;" > labore< / span > < span style = "color:#846002;" > et< / span > < span style = "color:#81BB0B;" > dolore< / span > < span style = "color:#E3DDD1;" > magna< / span > < span style = "color:#877C09;" > aliqua< / span > . < span style = "color:#CB6967;" > Ut< / span > < span style = "color:#B38347;" > enim< / span > < span style = "color:#4B8A53;" > ad< / span > < span style = "color:#078AC6;" > minim< / span > < span style = "color:#D2F7E3;" > veniam< / span > , < span style = "color:#6BD5A2;" > quis< / span > < span style = "color:#2B37D2;" > nostrud< / span > < span style = "color:#C592D6;" > exercitation< / span > < span style = "color:#0EB9D1;" > ullamco< / span > < span style = "color:#9BC026;" > laboris< / span > < span style = "color:#872CC2;" > nisi< / span > < span style = "color:#93B1CD;" > ut< / span > < span style = "color:#7DB82B;" > aliquip< / span > < span style = "color:#1CED95;" > ex< / span > < span style = "color:#C0504C;" > ea< / span > < span style = "color:#5DA8B5;" > commodo< / span > < span style = "color:#B762A6;" > consequat< / span > . < span style = "color:#2FCB06;" > Duis< / span > < span style = "color:#EADF81;" > aute< / span > < span style = "color:#0602B8;" > irure< / span > < span style = "color:#45EEDD;" > dolor< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#8B2DEF;" > reprehenderit< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#790B62;" > voluptate< / span > < span style = "color:#7486E8;" > velit< / span > < span style = "color:#33E7F2;" > esse< / span > < span style = "color:#DE099F;" > cillum< / span > < span style = "color:#81BB0B;" > dolore< / span > < span style = "color:#C514CD;" > eu< / span > < span style = "color:#B4B15A;" > fugiat< / span > < span style = "color:#93AA9C;" > nulla< / span > < span style = "color:#83967C;" > pariatur< / span > . < span style = "color:#EDD318;" > Excepteur< / span > < span style = "color:#580A2A;" > sint< / span > < span style = "color:#7DC184;" > occaecat< / span > < span style = "color:#BCEEAB;" > cupidatat< / span > < span style = "color:#EA0503;" > non< / span > < span style = "color:#0AC6DC;" > proident< / span > , < span style = "color:#90C0A3;" > sunt< / span > < span style = "color:#5E0D47;" > in< / span > < span style = "color:#0C0B4B;" > culpa< / span > < span style = "color:#B0E1D5;" > qui< / span > < span style = "color:#F8F0B6;" > officia< / span > < span style = "color:#FFF0B6;" > deserunt< / span > < span style = "color:#115AE8;" > mollit< / span > < span style = "color:#6EC31F;" > anim< / span > < span style = "color:#10B00E;" > id< / span > < span style = "color:#8ADFA4;" > est< / span > < span style = "color:#7EBB61;" > laborum< / span > . < / p >
## Possible Improvements
## Possible Improvements
- Provide HSV or HSL color values
There's a few places where this code could be meaningfully improved.
- Light/dark mode awareness
- It'd be nice to have HSL/HSV colors as an option. I've personally never been in a situation where RGB wasn't enough to do what I needed, but they exist for a reason. [HSLuv ](https://www.hsluv.org/ ) claims to better capture colors as perceived by the human eye and that sounds pretty neat.
- Accessibility. The colors chosen are effectively random with no regard for color schemes, background, display device capability
- Accessibility and consistency. Sometimes the color for a word will be almost identical to its background making portions of the text hard or impossible to read. It'd be cool to be able to limit color generation to values within certain ranges of a color palette. This is probably doable with another application of `Scale` .