Browse Source

Support RGB tuples for palette input

pull/3/head
makeworld 5 years ago
parent
commit
97d78f9de3
  1. 2
      README.md
  2. 4
      main.go
  3. 39
      subcommand_helpers.go

2
README.md

@ -34,7 +34,7 @@ It does not support images that make use of the alpha channel (transparency), bu
More methods of dithering are being worked on, such as Riemersma, Yuliluoma, and blue noise. If you'd like to help out with development of those methods, or request a new one, please make an issue in my [dither](https://github.com/makeworld-the-better-one/dither) library repo, not this one.
## Features
- Set palette using hex codes, number 0-255 (grayscale), or [SVG color names](https://www.w3.org/TR/SVG11/types.html#ColorKeywords)
- Set palette using RGB tuples, hex codes, number 0-255 (grayscale), or [SVG color names](https://www.w3.org/TR/SVG11/types.html#ColorKeywords)
- All colors are interpreted in the sRGB colorspace
- Optionally recolor image with a different palette after dithering
- Set dithering strength

4
main.go

@ -31,8 +31,8 @@ func main() {
description = `
Colors (for --palette and --recolor) are entered as a single quoted argument.
They can be separated by spaces and commas. Colors can be formatted as hex
codes (case-insensitive, with or without the '#'), a single number from 0-255
They can be separated by spaces and commas. Colors can be formatted as RGB tuples,
hex codes (case-insensitive, with or without the '#'), a single number from 0-255
for grayscale, or a color name from the SVG 1.1 spec (aka the HTML or W3C
color names). All colors are interpreted in the sRGB colorspace.

39
subcommand_helpers.go

@ -66,7 +66,7 @@ func globalFlag(flag string, c *cli.Context) interface{} {
func globalIsSet(flag string, c *cli.Context) bool {
ancestor := c.Lineage()[len(c.Lineage())-1]
if len(ancestor.Args().Slice()) == 0 {
// See globalFlag
// See globalFlag for why this if statement exists
return c.Lineage()[len(c.Lineage())-2].IsSet(flag)
}
return ancestor.IsSet(flag)
@ -88,8 +88,11 @@ func parseArgs(args []string, splitRunes string) []string {
return finalArgs
}
func hex2Color(hex string) (color.RGBA, error) {
func hexToColor(hex string) (color.RGBA, error) {
// Modified from https://github.com/lucasb-eyer/go-colorful/blob/v1.2.0/colors.go#L333
hex = strings.TrimPrefix(hex, "#")
format := "%02x%02x%02x"
var r, g, b uint8
n, err := fmt.Sscanf(strings.ToLower(hex), format, &r, &g, &b)
@ -97,7 +100,20 @@ func hex2Color(hex string) (color.RGBA, error) {
return color.RGBA{}, err
}
if n != 3 {
return color.RGBA{}, fmt.Errorf("%v is not a hex color", hex)
return color.RGBA{}, fmt.Errorf("%s is not a hex color", hex)
}
return color.RGBA{r, g, b, 255}, nil
}
func rgbToColor(s string) (color.RGBA, error) {
format := "%d,%d,%d"
var r, g, b uint8
n, err := fmt.Sscanf(s, format, &r, &g, &b)
if err != nil {
return color.RGBA{}, err
}
if n != 3 {
return color.RGBA{}, fmt.Errorf("%s is not an RGB tuple", s)
}
return color.RGBA{r, g, b, 255}, nil
}
@ -105,13 +121,22 @@ func hex2Color(hex string) (color.RGBA, error) {
// parseColors takes args and turns them into a color slice. All returned
// colors are guaranteed to only be color.RGBA.
func parseColors(flag string, c *cli.Context) ([]color.Color, error) {
args := parseArgs([]string{globalFlag(flag, c).(string)}, " ,#")
args := parseArgs([]string{globalFlag(flag, c).(string)}, " ")
colors := make([]color.Color, len(args))
for i, arg := range args {
// Try to parse as hex, then grayscale, then HTML colors, then fail
// Try to parse as RGB numbers, then hex, then grayscale, then SVG colors, then fail
if strings.Count(arg, ",") == 2 {
rgbColor, err := rgbToColor(arg)
if err != nil {
return nil, fmt.Errorf("%s: %s is not a valid RGB tuple. Example: 25,200,150", flag, arg)
}
colors[i] = rgbColor
continue
}
hexColor, err := hex2Color(arg)
hexColor, err := hexToColor(arg)
if err == nil {
colors[i] = hexColor
continue
@ -132,7 +157,7 @@ func parseColors(flag string, c *cli.Context) ([]color.Color, error) {
continue
}
return nil, fmt.Errorf("%s: %s not recognized as a hex code, number 0-255, or HTML color name", flag, arg)
return nil, fmt.Errorf("%s: %s not recognized as an RGB tuple, hex code, number 0-255, or SVG color name", flag, arg)
}
return colors, nil

Loading…
Cancel
Save