|
1 | 1 | # vibrant
|
2 | 2 |
|
3 |
| -go port of the [Android awesome Palette class](https://android.googlesource.com/platform/frameworks/support/+/b14fc7c/v7/palette/src/android/support/v7/graphics/) |
| 3 | +[](https://godoc.org/github.com/generaltso/vibrant) |
4 | 4 |
|
5 |
| -which I translated from this beautifully cleaned up version: |
6 |
| -https://github.com/Infinity/Iris |
7 | 5 |
|
8 |
| -and was first made aware of by [this Google I/O 2014 presentation](https://www.youtube.com/watch?v=ctzWKRlTYHQ?t=451) |
| 6 | +Extract prominent colors from images. Go port of the [Android awesome Palette class](https://android.googlesource.com/platform/frameworks/support/+/b14fc7c/v7/palette/src/android/support/v7/graphics/) aka [Vibrant.js](https://github.com/jariz/vibrant.js). |
9 | 7 |
|
10 |
| -and of course |
11 |
| -https://github.com/jariz/vibrant.js |
| 8 | + |
12 | 9 |
|
13 |
| -and last but not least |
14 |
| -https://github.com/akfish/node-vibrant |
| 10 | +# install |
15 | 11 |
|
16 |
| -## Why |
| 12 | +``` |
| 13 | +go get github.com/generaltso/vibrant |
| 14 | +``` |
| 15 | + |
| 16 | +# usage |
17 | 17 |
|
18 |
| -I was dissatisfied with the performance of the above JavaScript ports. One day, I mocked up an HTML thumbnail view gallery thing and wanted to use "Vibrancy" to decorate the buttons, links, titles, etc. The page had about 25 wallpaper images I used just as placeholders and using Vibrant.js brought my browser to its knees. |
| 18 | +```go |
| 19 | +// example: create css stylesheet from image file |
| 20 | +checkErr := func(err error) { if err != nil { panic(err) } } |
19 | 21 |
|
20 |
| -Yes, I could have just thumbnailed the wallpapers and carried on like a normal person, but this act of stupidity got me thinking: why do this calculation in the browser? If it kills my browser like this, imagine what it must do to mobiles. And it's not like the images are dynamic (in my use case, anyway). They're dynamic in the sense that users upload them but once they're there, they don't change and neither does their palette. |
| 22 | +f, err := os.Open("some_image.jpg") |
| 23 | +checkErr(err) |
| 24 | +defer f.Close() |
21 | 25 |
|
22 |
| -So why not do it server-side and cache the result? As a CSS file, which I can then use with `<style scoped>` e.g.: |
23 |
| -```HTML |
24 |
| -<section class="card"> |
25 |
| - <style scoped>@import "image1-vibrant.css";</style> |
26 |
| - <h1 class="darkvibrant">~Fancy Title~</h1> |
27 |
| - <div class="card-border muted"> |
28 |
| - <img src="image1-thumb.jpg"> |
29 |
| - </div> |
30 |
| - <div class="card-caption darkmuted"> |
31 |
| - <button class="vibrant">Call to action!</button> |
32 |
| - </div> |
33 |
| -</section> |
| 26 | +img, _, err := image.Decode(f) |
| 27 | +checkErr(err) |
| 28 | + |
| 29 | +palette, err := vibrant.NewPaletteFromImage(img) |
| 30 | +checkErr(err) |
| 31 | + |
| 32 | +for name, swatch := range palette.ExtractAwesome() { |
| 33 | + fmt.Printf("/* %s (population: %d) */\n%s\n\n", name, swatch.Population, swatch) |
| 34 | +} |
34 | 35 | ```
|
35 | 36 |
|
| 37 | +###### output: |
| 38 | +```css |
| 39 | +/* LightMuted (population: 253) */ |
| 40 | +.lightmuted{background-color:#cbc0a2;color:#000000;} |
36 | 41 |
|
37 |
| -It's probably not a good idea to over-do it like that with the colors, but the point is that you *can* do it in the first place. |
| 42 | +/* DarkMuted (population: 11069) */ |
| 43 | +.darkmuted{background-color:#5b553f;color:#ffffff;} |
38 | 44 |
|
39 |
| -This approach also allows for graceful fallback to a default palette set |
| 45 | +/* Vibrant (population: 108) */ |
| 46 | +.vibrant{background-color:#dfd013;color:#000000;} |
40 | 47 |
|
41 |
| -Perhaps I should stop trying to words **here is an example of scoped css**, view source until it makes sense: |
42 |
| -http://var.abl.cl/scoped-css |
| 48 | +/* LightVibrant (population: 87) */ |
| 49 | +.lightvibrant{background-color:#f4ed7d;color:#000000;} |
| 50 | + |
| 51 | +/* DarkVibrant (population: 2932) */ |
| 52 | +.darkvibrant{background-color:#917606;color:#ffffff;} |
| 53 | + |
| 54 | +/* Muted (population: 4098) */ |
| 55 | +.muted{background-color:#a58850;color:#000000;} |
43 | 56 |
|
44 |
| -## Usage |
45 |
| -```bash |
46 |
| -$ go get github.com/generaltso/vibrant |
47 | 57 | ```
|
48 | 58 |
|
49 |
| -```go |
50 |
| -package main |
51 |
| - |
52 |
| -import ( |
53 |
| - "fmt" |
54 |
| - "image" |
55 |
| - _ "image/jpeg" |
56 |
| - "log" |
57 |
| - "os" |
58 |
| -) |
59 |
| - |
60 |
| -import "github.com/generaltso/vibrant" |
61 |
| - |
62 |
| -func main() { |
63 |
| - file, err := os.Open("some_image.jpg") |
64 |
| - if err != nil { |
65 |
| - log.Fatalln(err) |
66 |
| - } |
67 |
| - img, _, err := image.Decode(file) |
68 |
| - if err != nil { |
69 |
| - log.Fatalln(err) |
70 |
| - } |
71 |
| - palette, err := vibrant.NewPaletteFromImage(img) |
72 |
| - if err != nil { |
73 |
| - log.Fatalln(err) |
74 |
| - } |
75 |
| - for name, swatch := range palette.ExtractAwesome() { |
76 |
| - fmt.Printf("name: %s, color: %s, population: %d\n", name /* or swatch.Name */, swatch.RGBHex(), swatch.Population) |
77 |
| - } |
78 |
| -} |
| 59 | +See [godoc reference](https://godoc.org/github.com/generaltso/vibrant) for full API. |
| 60 | + |
| 61 | +# bonus round |
| 62 | + |
| 63 | +## reference implementation/command line tool |
| 64 | +``` |
| 65 | +go get github.com/generaltso/vibrant/cmd/vibrant |
79 | 66 | ```
|
80 | 67 |
|
81 |
| -There is also a command-line tool in vibrant/: |
82 |
| -```bash |
83 |
| -$ cd vibrant && go install |
84 |
| -$ vibrant some_image.png |
85 | 68 | ```
|
86 |
| -(it prints CSS to stdout) |
| 69 | +usage: vibrant [options] file |
| 70 | +
|
| 71 | +options: |
| 72 | + -compress |
| 73 | + Strip whitespace from output. |
| 74 | + -css |
| 75 | + Output results in CSS. |
| 76 | + -json |
| 77 | + Output results in JSON. |
| 78 | + -lowercase |
| 79 | + Use lowercase only for all output. (default true) |
| 80 | + -rgb |
| 81 | + Output RGB instead of HTML hex, e.g. #ffffff. |
| 82 | +``` |
| 83 | + |
| 84 | +## webapp |
87 | 85 |
|
88 |
| -And there is a simple demo application which is a little more visual: |
89 |
| -```bash |
90 |
| -$ cd demo && go run app.go |
91 |
| -Listening on 0.0.0.0:8080... |
92 | 86 | ```
|
93 |
| - |
| 87 | +go get github.com/generaltso/vibrant |
| 88 | +cd $GOPATH/github.com/generaltso/vibrant |
| 89 | +go run webapp.go |
| 90 | +# open http://localhost:8080/ in a browser |
| 91 | +``` |
94 | 92 |
|
95 | 93 |
|
96 |
| -**This API and the tools provided are a work-in-progress proof-of-concept and certainly could use improvement, better naming, etc.** |
| 94 | +# thanks |
97 | 95 |
|
98 |
| -Comments, feedback and pull requests are welcome! |
99 |
| -[email me ](mailto:[email protected]) |
100 |
| -[find this project on github](https://github.com/generaltso/vibrant) |
| 96 | +https://github.com/Infinity/Iris |
| 97 | + |
| 98 | +[This Google I/O 2014 presentation](https://www.youtube.com/watch?v=ctzWKRlTYHQ?t=451) |
| 99 | + |
| 100 | +https://github.com/jariz/vibrant.js |
| 101 | + |
| 102 | +https://github.com/akfish/node-vibrant |
0 commit comments