letter_avatar_for7 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +83 -0
- data/README.md +174 -0
- data/Roboto-Medium +0 -0
- data/lib/letter_avatar/avatar.rb +98 -0
- data/lib/letter_avatar/avatar_helper.rb +24 -0
- data/lib/letter_avatar/colors.rb +308 -0
- data/lib/letter_avatar/configuration.rb +77 -0
- data/lib/letter_avatar/has_avatar.rb +26 -0
- data/lib/letter_avatar/version.rb +3 -0
- data/lib/letter_avatar.rb +57 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fd7352f216b49312014b1d235ec9a4ef0125b777a38cece0a9a2d8e27209d7fb
|
4
|
+
data.tar.gz: e986e7540094d187d350e2cc432aad875c5f0dff52c249587fd58fcd5c360ea3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c350bb8bc8ba4c3400a8e102e45f60423c2b151e92fdcbc6733f9a035e45dad16eaf5403dfac76548edf7bad5cb46e4c43ac433ad494d226b549f0f65534c4c
|
7
|
+
data.tar.gz: 64e86db174a123d70722daba92ee939b148d73f50c55348faa6159e99b6c953c4da3b94ab4fb1e43d4a5080ed2d0efd96aea4833cd9de4562d0e4f502e8e0c69
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
0.3.9
|
2
|
+
-----
|
3
|
+
|
4
|
+
- small minor fixes and cleanups.
|
5
|
+
|
6
|
+
0.3.8
|
7
|
+
-----
|
8
|
+
|
9
|
+
- added `LetterAvatar.font` config option.
|
10
|
+
|
11
|
+
0.3.7
|
12
|
+
-----
|
13
|
+
|
14
|
+
- added `LetterAvatar.custom_palette` config option.
|
15
|
+
- bumped `FULLSIZE` to 600.
|
16
|
+
|
17
|
+
0.3.6
|
18
|
+
-----
|
19
|
+
|
20
|
+
- added `LetterAvatar.letters_count` config option.
|
21
|
+
- added `LetterAvatar.pointsize` config option.
|
22
|
+
|
23
|
+
0.3.5
|
24
|
+
-----
|
25
|
+
|
26
|
+
- `LetterAvatar::HasAvatar` helper module cleanup
|
27
|
+
- `LetterAvatar.path_to_url` helper method
|
28
|
+
|
29
|
+
0.3.4
|
30
|
+
-----
|
31
|
+
|
32
|
+
- enhanced `LetterAvatar::HasAvatar` helper module
|
33
|
+
|
34
|
+
0.3.3
|
35
|
+
-----
|
36
|
+
|
37
|
+
- removed `-interpolate` imagemagick option - it's removed in IMv7
|
38
|
+
|
39
|
+
0.3.2
|
40
|
+
-----
|
41
|
+
|
42
|
+
- extend objects with `ActionView::Helpers::AssetTagHelper`
|
43
|
+
|
44
|
+
0.3.1
|
45
|
+
-----
|
46
|
+
|
47
|
+
- added `LetterAvatar.fill_color` config option.
|
48
|
+
|
49
|
+
0.3.0
|
50
|
+
-----
|
51
|
+
|
52
|
+
- Removed `activesupport` dependency.
|
53
|
+
|
54
|
+
0.2.0
|
55
|
+
-----
|
56
|
+
|
57
|
+
- Removed `posix-spawn` dependency, Open3 speed is ok.
|
58
|
+
|
59
|
+
0.1.11
|
60
|
+
------
|
61
|
+
|
62
|
+
- Windows support.
|
63
|
+
|
64
|
+
0.1.10
|
65
|
+
------
|
66
|
+
|
67
|
+
- `LetterAvatar::AvatarHelper` module tweaks
|
68
|
+
- `letter_avatar_url` method, returning avatar proper url
|
69
|
+
- `letter_avatar_tag` doeas not require `ActionView::Helpers::AssetTagHelper`
|
70
|
+
|
71
|
+
0.1.9
|
72
|
+
-----
|
73
|
+
|
74
|
+
- `LetterAvatar::Configuration` module, `mattr_accessor` (depending on `ActiveSupport`) removed
|
75
|
+
|
76
|
+
fixes [#7](https://github.com/ksz2k/letter_avatar/issues/7)
|
77
|
+
|
78
|
+
0.1.5
|
79
|
+
-----
|
80
|
+
|
81
|
+
- Use [posix-spawn](https://github.com/rtomayko/posix-spawn) to instead of Kernel#exec to get better performance.
|
82
|
+
|
83
|
+
> fork(2) calls slow down as the parent process uses more memory due to the need to copy page tables.
|
data/README.md
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# LetterAvatar
|
2
|
+
|
3
|
+
Gem for creating letter avatar from user's name (or any other strong / character).
|
4
|
+
|
5
|
+
Code extracted from [discourse](https://www.discourse.org/) source (thanks guys!) - I needed this functionality in three projects, so here's the gem! :-)
|
6
|
+
|
7
|
+
[](https://badge.fury.io/rb/letter_avatar)
|
8
|
+
[](https://codeclimate.com/github/ksz2k/letter_avatar)
|
9
|
+
|
10
|
+
## Examples
|
11
|
+
|
12
|
+
#### Google's Inbox Palette
|
13
|
+
|
14
|
+
<img src="https://cloud.githubusercontent.com/assets/5518/13031513/43eefa76-d30b-11e5-8f06-85f8eb2a4fb6.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031514/43ef6d8a-d30b-11e5-9fbc-38ae526b56b3.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031517/43f0da12-d30b-11e5-8fef-6c7daf235a54.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031515/43f0568c-d30b-11e5-95c5-1653361d4443.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031512/43eebcc8-d30b-11e5-9f95-0093bfadd182.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031516/43f0d0bc-d30b-11e5-8822-f01a6a138ff8.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031519/44382430-d30b-11e5-96e4-bcd7ce5eb155.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031518/44378d04-d30b-11e5-9400-55ff46b94cbe.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031521/443a03cc-d30b-11e5-8467-9592e9dbb2ae.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031523/443badc6-d30b-11e5-9d72-45613018cab4.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031520/44394e14-d30b-11e5-966c-2eada89295c9.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031522/443a71fe-d30b-11e5-88f4-37d1fd220abb.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031525/44752b1e-d30b-11e5-8290-ed8888055e64.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031524/4471cef6-d30b-11e5-9f4c-004f993dd27b.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031526/4475a990-d30b-11e5-8be3-c8f4482dee03.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031527/44772482-d30b-11e5-92f0-b9190c312d70.png" width="60" /> <img src="https://cloud.githubusercontent.com/assets/5518/13031528/447804ce-d30b-11e5-8002-9424d5474ddb.png" width="60" />
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
System requirements
|
19
|
+
|
20
|
+
```bash
|
21
|
+
$ sudo apt-get install -y imagemagick
|
22
|
+
```
|
23
|
+
|
24
|
+
Mac OS X
|
25
|
+
|
26
|
+
```bash
|
27
|
+
$ brew install imagemagick ghostscript
|
28
|
+
```
|
29
|
+
|
30
|
+
Add this line to your application's Gemfile:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
gem 'letter_avatar'
|
34
|
+
```
|
35
|
+
|
36
|
+
And then execute:
|
37
|
+
|
38
|
+
```bash
|
39
|
+
$ bundle
|
40
|
+
```
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
$ gem install letter_avatar
|
46
|
+
```
|
47
|
+
|
48
|
+
## Configuration
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
LetterAvatar.setup do |config|
|
52
|
+
config.fill_color = 'rgba(255, 255, 255, 1)' # default is 'rgba(255, 255, 255, 0.65)'
|
53
|
+
config.cache_base_path = 'public/system/lets' # default is 'public/system'
|
54
|
+
config.colors_palette = :iwanthue # default is :google
|
55
|
+
config.weight = 500 # default is 300
|
56
|
+
config.annotate_position = '-0+10' # default is -0+5
|
57
|
+
config.letters_count = 2 # default is 1
|
58
|
+
config.pointsize = 70 # default is 140
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Color palette
|
63
|
+
|
64
|
+
We have three color palettes implemented: `iwanthue`, `google` and `custom`.
|
65
|
+
|
66
|
+
Each of them have different colors, but the `iwanthue` also differently calculates the color for specified username.
|
67
|
+
|
68
|
+
The `google` selected will generate the same avatar for both, "Krzysiek" and "ksz2k" usernames given (both of them starts with letter "k"), but `iwanthue` will calculate it's md5 and then selects color, so there's huge chance that these usernames get different colors.
|
69
|
+
|
70
|
+
##### Custom palette definition
|
71
|
+
|
72
|
+
You can define your own `custom` palette:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
LetterAvatar.setup do |config|
|
76
|
+
config.colors_palette = :custom
|
77
|
+
config.custom_palette = [[120, 132, 205], [91, 149, 249], [72, 194, 249], [69, 208, 226]]
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
##### Custom font definition
|
82
|
+
|
83
|
+
You can define your own `custom` palette:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
LetterAvatar.setup do |config|
|
87
|
+
config.font = File.join(File.expand_path('../../', File.dirname(__FILE__)), 'app/assets/fonts', 'font_name.ext')
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
## Usage
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
LetterAvatar.generate 'ksz2k', 200
|
95
|
+
=> "public/system/letter_avatars/2/K/87_178_230/200.png"
|
96
|
+
```
|
97
|
+
|
98
|
+
### In your controllers / views
|
99
|
+
|
100
|
+
There's also helper for this. To use it, you need:
|
101
|
+
|
102
|
+
* in your helper (eg. `ApplicationHelper`) or controller:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
include LetterAvatar::AvatarHelper
|
106
|
+
```
|
107
|
+
|
108
|
+
* and in your view:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
letter_avatar_for('ksz2k', 200)
|
112
|
+
=> "public/system/letter_avatars/2/K/87_178_230/200.png"
|
113
|
+
# or
|
114
|
+
letter_avatar_url('ksz2k', 200)
|
115
|
+
=> "/system/letter_avatars/2/K/87_178_230/200.png"
|
116
|
+
# or even
|
117
|
+
letter_avatar_tag('ksz2k', 200, class: 'av')
|
118
|
+
=> "<img class=\"av\" alt=\"ksz2k\" src=\"/system/letter_avatars/2/K/87_178_230/200.png\" />"
|
119
|
+
```
|
120
|
+
|
121
|
+
### In your model
|
122
|
+
|
123
|
+
Say, you have a model `User` (which must have attribute or method `name`)
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
require 'letter_avatar/has_avatar'
|
127
|
+
|
128
|
+
class User
|
129
|
+
include LetterAvatar::HasAvatar
|
130
|
+
...
|
131
|
+
|
132
|
+
def name
|
133
|
+
'ksz2k'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
Then, in your views you can use:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
@user.avatar_path(200)
|
142
|
+
=> "public/system/letter_avatars/2/K/87_178_230/200.png"
|
143
|
+
# or
|
144
|
+
@user.avatar_url(200)
|
145
|
+
=> "/system/letter_avatars/2/K/87_178_230/200.png"
|
146
|
+
```
|
147
|
+
|
148
|
+
### Way to support non [a-z0-9] charsets
|
149
|
+
|
150
|
+
```rb
|
151
|
+
class User
|
152
|
+
def username_for_avatar
|
153
|
+
# Translate Chinese hanzi to pinyin
|
154
|
+
# https://github.com/flyerhzm/chinese_pinyin
|
155
|
+
Pinyin.t(self.username)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
Then you can get right avatar now:
|
161
|
+
|
162
|
+
```rb
|
163
|
+
letter_avatar_for(user.username_for_avatar, 200)
|
164
|
+
# or
|
165
|
+
letter_avatar_tag(user.username_for_avatar, 200, class: 'av')
|
166
|
+
```
|
167
|
+
|
168
|
+
## Contributing
|
169
|
+
|
170
|
+
1. Fork it
|
171
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
172
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
173
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
174
|
+
5. Create new Pull Request
|
data/Roboto-Medium
ADDED
Binary file
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module LetterAvatar
|
4
|
+
class Avatar
|
5
|
+
# BUMP UP if avatar algorithm changes
|
6
|
+
VERSION = 2
|
7
|
+
|
8
|
+
# Largest avatar generated, one day when pixel ratio hit 3
|
9
|
+
# we will need to change this
|
10
|
+
FULLSIZE = 600
|
11
|
+
|
12
|
+
FILL_COLOR = 'rgba(255, 255, 255, 0.65)'.freeze
|
13
|
+
|
14
|
+
FONT_FILENAME = File.join(File.expand_path('../../', File.dirname(__FILE__)), 'Roboto-Medium')
|
15
|
+
|
16
|
+
class << self
|
17
|
+
class Identity
|
18
|
+
attr_accessor :color, :letter
|
19
|
+
|
20
|
+
def self.from_username(username)
|
21
|
+
identity = new
|
22
|
+
identity.color = LetterAvatar::Colors.for(username)
|
23
|
+
letters = username.split(/\s+/).map {|word| word[0]}.join('')[0..LetterAvatar.letters_count - 1]
|
24
|
+
identity.letter = letters.upcase
|
25
|
+
|
26
|
+
identity
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def cache_path
|
31
|
+
"#{LetterAvatar.cache_base_path || 'public/system'}/letter_avatars/#{VERSION}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate(username, size, opts = nil)
|
35
|
+
identity = Identity.from_username(username)
|
36
|
+
|
37
|
+
cache = true
|
38
|
+
cache = false if opts && opts[:cache] == false
|
39
|
+
|
40
|
+
size = FULLSIZE if size > FULLSIZE
|
41
|
+
filename = cached_path(identity, size)
|
42
|
+
|
43
|
+
return filename if cache && File.exist?(filename)
|
44
|
+
|
45
|
+
fullsize = fullsize_path(identity)
|
46
|
+
if !cache || !File.exist?(fullsize)
|
47
|
+
generate_fullsize(identity)
|
48
|
+
end
|
49
|
+
LetterAvatar.resize(fullsize, filename, size, size) if size != FULLSIZE
|
50
|
+
|
51
|
+
filename
|
52
|
+
end
|
53
|
+
|
54
|
+
def cached_path(identity, size)
|
55
|
+
dir = "#{cache_path}/#{identity.letter}/#{identity.color.join('_')}"
|
56
|
+
FileUtils.mkdir_p(dir)
|
57
|
+
|
58
|
+
"#{dir}/#{size}.png"
|
59
|
+
end
|
60
|
+
|
61
|
+
def fullsize_path(identity)
|
62
|
+
cached_path(identity, FULLSIZE)
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_fullsize(identity)
|
66
|
+
filename = fullsize_path(identity)
|
67
|
+
|
68
|
+
LetterAvatar.execute(
|
69
|
+
%W(
|
70
|
+
convert
|
71
|
+
-size #{FULLSIZE}x#{FULLSIZE}
|
72
|
+
xc:#{to_rgb(identity.color)}
|
73
|
+
-pointsize #{LetterAvatar.pointsize}
|
74
|
+
-font #{LetterAvatar.font}
|
75
|
+
-weight #{LetterAvatar.weight}
|
76
|
+
-fill '#{LetterAvatar.fill_color}'
|
77
|
+
-gravity Center
|
78
|
+
-annotate #{LetterAvatar.annotate_position} '#{identity.letter}'
|
79
|
+
'#{filename}'
|
80
|
+
).join(' ')
|
81
|
+
)
|
82
|
+
|
83
|
+
filename
|
84
|
+
end
|
85
|
+
|
86
|
+
def darken(color, pct)
|
87
|
+
color.map do |n|
|
88
|
+
(n.to_f * pct).to_i
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_rgb(color)
|
93
|
+
r, g, b = color
|
94
|
+
"'rgb(#{r},#{g},#{b})'"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module LetterAvatar
|
2
|
+
module AvatarHelper
|
3
|
+
def letter_avatar_for(name, size = 64)
|
4
|
+
LetterAvatar.generate(name, size)
|
5
|
+
end
|
6
|
+
|
7
|
+
def letter_avatar_url_for(avatar_path)
|
8
|
+
LetterAvatar.path_to_url(avatar_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def letter_avatar_url(name, size = 64)
|
12
|
+
letter_avatar_url_for(letter_avatar_for(name, size))
|
13
|
+
end
|
14
|
+
|
15
|
+
def letter_avatar_tag(name, size = 64, options = {})
|
16
|
+
if defined?(ActionView::Helpers::AssetTagHelper)
|
17
|
+
extend ActionView::Helpers::AssetTagHelper
|
18
|
+
image_tag(letter_avatar_url(name, size), options.merge(alt: name))
|
19
|
+
else
|
20
|
+
"<img alt=\"#{name}\" class\"#{options.fetch(:class)}\" src=\"#{letter_avatar_url(name, size)}\" />"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module LetterAvatar
|
4
|
+
module Colors
|
5
|
+
PALETTES = [:google, :iwanthue, :custom]
|
6
|
+
|
7
|
+
GOOGLE_COLORS = [
|
8
|
+
[226, 95, 81], # A
|
9
|
+
[242, 96, 145], # B
|
10
|
+
[187, 101, 202], # C
|
11
|
+
[149, 114, 207], # D
|
12
|
+
[120, 132, 205], # E
|
13
|
+
[91, 149, 249], # F
|
14
|
+
[72, 194, 249], # G
|
15
|
+
[69, 208, 226], # H
|
16
|
+
[72, 182, 172], # I
|
17
|
+
[82, 188, 137], # J
|
18
|
+
[155, 206, 95], # K
|
19
|
+
[212, 227, 74], # L
|
20
|
+
[254, 218, 16], # M
|
21
|
+
[247, 192, 0], # N
|
22
|
+
[255, 168, 0], # O
|
23
|
+
[255, 138, 96], # P
|
24
|
+
[194, 194, 194], # Q
|
25
|
+
[143, 164, 175], # R
|
26
|
+
[162, 136, 126], # S
|
27
|
+
[163, 163, 163], # T
|
28
|
+
[175, 181, 226], # U
|
29
|
+
[179, 155, 221], # V
|
30
|
+
[194, 194, 194], # W
|
31
|
+
[124, 222, 235], # X
|
32
|
+
[188, 170, 164], # Y
|
33
|
+
[173, 214, 125] # Z
|
34
|
+
].freeze
|
35
|
+
|
36
|
+
IWANTHUE_COLORS = [
|
37
|
+
[198, 125, 40],
|
38
|
+
[61, 155, 243],
|
39
|
+
[74, 243, 75],
|
40
|
+
[238, 89, 166],
|
41
|
+
[52, 240, 224],
|
42
|
+
[177, 156, 155],
|
43
|
+
[240, 120, 145],
|
44
|
+
[111, 154, 78],
|
45
|
+
[237, 179, 245],
|
46
|
+
[237, 101, 95],
|
47
|
+
[89, 239, 155],
|
48
|
+
[43, 254, 70],
|
49
|
+
[163, 212, 245],
|
50
|
+
[65, 152, 142],
|
51
|
+
[165, 135, 246],
|
52
|
+
[181, 166, 38],
|
53
|
+
[187, 229, 206],
|
54
|
+
[77, 164, 25],
|
55
|
+
[179, 246, 101],
|
56
|
+
[234, 93, 37],
|
57
|
+
[225, 155, 115],
|
58
|
+
[142, 140, 188],
|
59
|
+
[223, 120, 140],
|
60
|
+
[249, 174, 27],
|
61
|
+
[244, 117, 225],
|
62
|
+
[137, 141, 102],
|
63
|
+
[75, 191, 146],
|
64
|
+
[188, 239, 142],
|
65
|
+
[164, 199, 145],
|
66
|
+
[173, 120, 149],
|
67
|
+
[59, 195, 89],
|
68
|
+
[222, 198, 220],
|
69
|
+
[68, 145, 187],
|
70
|
+
[236, 204, 179],
|
71
|
+
[159, 195, 72],
|
72
|
+
[188, 121, 189],
|
73
|
+
[166, 160, 85],
|
74
|
+
[181, 233, 37],
|
75
|
+
[236, 177, 85],
|
76
|
+
[121, 147, 160],
|
77
|
+
[234, 218, 110],
|
78
|
+
[241, 157, 191],
|
79
|
+
[62, 200, 234],
|
80
|
+
[133, 243, 34],
|
81
|
+
[88, 149, 110],
|
82
|
+
[59, 228, 248],
|
83
|
+
[183, 119, 118],
|
84
|
+
[251, 195, 45],
|
85
|
+
[113, 196, 122],
|
86
|
+
[197, 115, 70],
|
87
|
+
[80, 175, 187],
|
88
|
+
[103, 231, 238],
|
89
|
+
[240, 72, 133],
|
90
|
+
[228, 149, 241],
|
91
|
+
[180, 188, 159],
|
92
|
+
[172, 132, 85],
|
93
|
+
[180, 135, 251],
|
94
|
+
[236, 194, 58],
|
95
|
+
[217, 176, 109],
|
96
|
+
[88, 244, 199],
|
97
|
+
[186, 157, 239],
|
98
|
+
[113, 230, 96],
|
99
|
+
[206, 115, 165],
|
100
|
+
[244, 178, 163],
|
101
|
+
[230, 139, 26],
|
102
|
+
[241, 125, 89],
|
103
|
+
[83, 160, 66],
|
104
|
+
[107, 190, 166],
|
105
|
+
[197, 161, 210],
|
106
|
+
[198, 203, 245],
|
107
|
+
[238, 117, 19],
|
108
|
+
[228, 119, 116],
|
109
|
+
[131, 156, 41],
|
110
|
+
[145, 178, 168],
|
111
|
+
[139, 170, 220],
|
112
|
+
[233, 95, 125],
|
113
|
+
[87, 178, 230],
|
114
|
+
[157, 200, 119],
|
115
|
+
[237, 140, 76],
|
116
|
+
[229, 185, 186],
|
117
|
+
[144, 206, 212],
|
118
|
+
[236, 209, 158],
|
119
|
+
[185, 189, 79],
|
120
|
+
[34, 208, 66],
|
121
|
+
[84, 238, 129],
|
122
|
+
[133, 140, 134],
|
123
|
+
[67, 157, 94],
|
124
|
+
[168, 179, 25],
|
125
|
+
[140, 145, 240],
|
126
|
+
[151, 241, 125],
|
127
|
+
[67, 162, 107],
|
128
|
+
[200, 156, 21],
|
129
|
+
[169, 173, 189],
|
130
|
+
[226, 116, 189],
|
131
|
+
[133, 231, 191],
|
132
|
+
[194, 161, 63],
|
133
|
+
[241, 77, 99],
|
134
|
+
[241, 217, 53],
|
135
|
+
[123, 204, 105],
|
136
|
+
[210, 201, 119],
|
137
|
+
[229, 108, 155],
|
138
|
+
[240, 91, 72],
|
139
|
+
[187, 115, 210],
|
140
|
+
[240, 163, 100],
|
141
|
+
[178, 217, 57],
|
142
|
+
[179, 135, 116],
|
143
|
+
[204, 211, 24],
|
144
|
+
[186, 135, 57],
|
145
|
+
[223, 176, 135],
|
146
|
+
[204, 148, 151],
|
147
|
+
[116, 223, 50],
|
148
|
+
[95, 195, 46],
|
149
|
+
[123, 160, 236],
|
150
|
+
[181, 172, 131],
|
151
|
+
[142, 220, 202],
|
152
|
+
[240, 140, 112],
|
153
|
+
[172, 145, 164],
|
154
|
+
[228, 124, 45],
|
155
|
+
[135, 151, 243],
|
156
|
+
[42, 205, 125],
|
157
|
+
[192, 233, 116],
|
158
|
+
[119, 170, 114],
|
159
|
+
[158, 138, 26],
|
160
|
+
[73, 190, 183],
|
161
|
+
[185, 229, 243],
|
162
|
+
[227, 107, 55],
|
163
|
+
[196, 205, 202],
|
164
|
+
[132, 143, 60],
|
165
|
+
[233, 192, 237],
|
166
|
+
[62, 150, 220],
|
167
|
+
[205, 201, 141],
|
168
|
+
[106, 140, 190],
|
169
|
+
[161, 131, 205],
|
170
|
+
[135, 134, 158],
|
171
|
+
[198, 139, 81],
|
172
|
+
[115, 171, 32],
|
173
|
+
[101, 181, 67],
|
174
|
+
[149, 137, 119],
|
175
|
+
[37, 142, 183],
|
176
|
+
[183, 130, 175],
|
177
|
+
[168, 125, 133],
|
178
|
+
[124, 142, 87],
|
179
|
+
[236, 156, 171],
|
180
|
+
[232, 194, 91],
|
181
|
+
[219, 200, 69],
|
182
|
+
[144, 219, 34],
|
183
|
+
[219, 95, 187],
|
184
|
+
[145, 154, 217],
|
185
|
+
[165, 185, 100],
|
186
|
+
[127, 238, 163],
|
187
|
+
[224, 178, 198],
|
188
|
+
[119, 153, 120],
|
189
|
+
[124, 212, 92],
|
190
|
+
[172, 161, 105],
|
191
|
+
[231, 155, 135],
|
192
|
+
[157, 132, 101],
|
193
|
+
[122, 185, 146],
|
194
|
+
[53, 166, 51],
|
195
|
+
[70, 163, 90],
|
196
|
+
[150, 190, 213],
|
197
|
+
[210, 107, 60],
|
198
|
+
[166, 152, 185],
|
199
|
+
[159, 194, 159],
|
200
|
+
[39, 141, 222],
|
201
|
+
[202, 176, 161],
|
202
|
+
[95, 140, 229],
|
203
|
+
[168, 142, 87],
|
204
|
+
[93, 170, 203],
|
205
|
+
[159, 142, 54],
|
206
|
+
[14, 168, 39],
|
207
|
+
[94, 150, 149],
|
208
|
+
[187, 206, 136],
|
209
|
+
[157, 224, 166],
|
210
|
+
[235, 158, 208],
|
211
|
+
[109, 232, 216],
|
212
|
+
[141, 201, 87],
|
213
|
+
[208, 124, 118],
|
214
|
+
[142, 125, 214],
|
215
|
+
[19, 237, 174],
|
216
|
+
[72, 219, 41],
|
217
|
+
[234, 102, 111],
|
218
|
+
[168, 142, 79],
|
219
|
+
[188, 135, 35],
|
220
|
+
[95, 155, 143],
|
221
|
+
[148, 173, 116],
|
222
|
+
[223, 112, 95],
|
223
|
+
[228, 128, 236],
|
224
|
+
[206, 114, 54],
|
225
|
+
[195, 119, 88],
|
226
|
+
[235, 140, 94],
|
227
|
+
[235, 202, 125],
|
228
|
+
[233, 155, 153],
|
229
|
+
[214, 214, 238],
|
230
|
+
[246, 200, 35],
|
231
|
+
[151, 125, 171],
|
232
|
+
[132, 145, 172],
|
233
|
+
[131, 142, 118],
|
234
|
+
[199, 126, 150],
|
235
|
+
[61, 162, 123],
|
236
|
+
[58, 176, 151],
|
237
|
+
[215, 141, 69],
|
238
|
+
[225, 154, 220],
|
239
|
+
[220, 77, 167],
|
240
|
+
[233, 161, 64],
|
241
|
+
[130, 221, 137],
|
242
|
+
[81, 191, 129],
|
243
|
+
[169, 162, 140],
|
244
|
+
[174, 177, 222],
|
245
|
+
[236, 174, 47],
|
246
|
+
[233, 188, 180],
|
247
|
+
[69, 222, 172],
|
248
|
+
[71, 232, 93],
|
249
|
+
[118, 211, 238],
|
250
|
+
[157, 224, 83],
|
251
|
+
[218, 105, 73],
|
252
|
+
[126, 169, 36]
|
253
|
+
].freeze
|
254
|
+
|
255
|
+
def self.for(username)
|
256
|
+
public_send("with_#{LetterAvatar.colors_palette}", username)
|
257
|
+
end
|
258
|
+
|
259
|
+
def self.with_iwanthue(username)
|
260
|
+
iwanthue[
|
261
|
+
::Digest::MD5.hexdigest(username)[0...15].to_i(16) % iwanthue.length
|
262
|
+
]
|
263
|
+
end
|
264
|
+
|
265
|
+
def self.with_google(username)
|
266
|
+
char = username[0].upcase
|
267
|
+
|
268
|
+
if /[A-Z]/ =~ char
|
269
|
+
# 65 is 'A' ord
|
270
|
+
idx = char.ord - 65
|
271
|
+
google[idx]
|
272
|
+
elsif /[\d]/ =~ char
|
273
|
+
google[char.to_i]
|
274
|
+
else
|
275
|
+
google[::Digest::MD5.hexdigest(username)[0...15].to_i(16) % google.length]
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.with_custom(username)
|
280
|
+
custom_palette = LetterAvatar.custom_palette
|
281
|
+
custom_palette[::Digest::MD5.hexdigest(username)[0...15].to_i(16) % custom_palette.length]
|
282
|
+
end
|
283
|
+
|
284
|
+
def self.valid_custom_palette?(palette)
|
285
|
+
return false unless palette.is_a?(Array)
|
286
|
+
return palette.all? do |color|
|
287
|
+
false unless color.is_a?(Array)
|
288
|
+
color.all? { |i| i.is_a?(Integer) }
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# Colors form Google Inbox
|
293
|
+
# https://inbox.google.com
|
294
|
+
def self.google
|
295
|
+
GOOGLE_COLORS
|
296
|
+
end
|
297
|
+
|
298
|
+
# palette of optimally disctinct colors
|
299
|
+
# cf. http://tools.medialab.sciences-po.fr/iwanthue/index.php
|
300
|
+
# parameters used:
|
301
|
+
# - H: 0 - 360
|
302
|
+
# - C: 0 - 2
|
303
|
+
# - L: 0.75 - 1.5
|
304
|
+
def self.iwanthue
|
305
|
+
IWANTHUE_COLORS
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module LetterAvatar
|
2
|
+
module Configuration
|
3
|
+
def cache_base_path
|
4
|
+
@cache_base_path
|
5
|
+
end
|
6
|
+
|
7
|
+
def cache_base_path=(v)
|
8
|
+
@cache_base_path = v
|
9
|
+
end
|
10
|
+
|
11
|
+
def font
|
12
|
+
@font || Avatar::FONT_FILENAME
|
13
|
+
end
|
14
|
+
|
15
|
+
def font=(v)
|
16
|
+
@font = v
|
17
|
+
end
|
18
|
+
|
19
|
+
def fill_color
|
20
|
+
@fill_color || Avatar::FILL_COLOR
|
21
|
+
end
|
22
|
+
|
23
|
+
def fill_color=(v)
|
24
|
+
@fill_color = v
|
25
|
+
end
|
26
|
+
|
27
|
+
def colors_palette
|
28
|
+
@colors_palette ||= :google
|
29
|
+
end
|
30
|
+
|
31
|
+
def colors_palette=(v)
|
32
|
+
@colors_palette = v if Colors::PALETTES.include?(v)
|
33
|
+
end
|
34
|
+
|
35
|
+
def custom_palette
|
36
|
+
@custom_palette ||= nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def custom_palette=(v)
|
40
|
+
@custom_palette = v
|
41
|
+
raise "Missing Custom Palette, please set config.custom_palette if using :custom" if @custom_palette.nil? && @colors_palette == :custom
|
42
|
+
raise "Invalid Custom Palette, please update config.custom_palette" unless Colors::valid_custom_palette?(@custom_palette)
|
43
|
+
end
|
44
|
+
|
45
|
+
def weight
|
46
|
+
@weight ||= 300
|
47
|
+
end
|
48
|
+
|
49
|
+
def weight=(v)
|
50
|
+
@weight = v
|
51
|
+
end
|
52
|
+
|
53
|
+
def annotate_position
|
54
|
+
@annotate_position ||= '-0+5'
|
55
|
+
end
|
56
|
+
|
57
|
+
def annotate_position=(v)
|
58
|
+
@annotate_position = v
|
59
|
+
end
|
60
|
+
|
61
|
+
def letters_count
|
62
|
+
@letters_count ||= 1
|
63
|
+
end
|
64
|
+
|
65
|
+
def letters_count=(v)
|
66
|
+
@letters_count = v
|
67
|
+
end
|
68
|
+
|
69
|
+
def pointsize
|
70
|
+
@pointsize ||= 140
|
71
|
+
end
|
72
|
+
|
73
|
+
def pointsize=(v)
|
74
|
+
@pointsize = v
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module LetterAvatar
|
2
|
+
module HasAvatar
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, InstanceMethods
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def self.included(base)
|
13
|
+
base.extend ClassMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
def avatar_path(size = 64)
|
17
|
+
LetterAvatar.generate(name, size)
|
18
|
+
end
|
19
|
+
|
20
|
+
def avatar_url(size = 64)
|
21
|
+
LetterAvatar.path_to_url(avatar_path(size))
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
require 'letter_avatar/version'
|
4
|
+
require 'letter_avatar/configuration'
|
5
|
+
require 'letter_avatar/avatar'
|
6
|
+
require 'letter_avatar/avatar_helper'
|
7
|
+
require 'letter_avatar/colors'
|
8
|
+
|
9
|
+
module LetterAvatar
|
10
|
+
extend LetterAvatar::Configuration
|
11
|
+
|
12
|
+
class ExecutionError < StandardError; end
|
13
|
+
|
14
|
+
def self.setup(&_block)
|
15
|
+
yield(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.resize(from, to, width, height)
|
19
|
+
execute(
|
20
|
+
# NOTE: ORDER is important!
|
21
|
+
%W[
|
22
|
+
magick
|
23
|
+
#{from}
|
24
|
+
-background transparent
|
25
|
+
-gravity center
|
26
|
+
-thumbnail #{width}x#{height}^
|
27
|
+
-extent #{width}x#{height}
|
28
|
+
-unsharp 2x0.5+0.7+0
|
29
|
+
-quality 98
|
30
|
+
#{to}
|
31
|
+
].join(' ')
|
32
|
+
)
|
33
|
+
true
|
34
|
+
rescue StandardError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.generate(username, size)
|
39
|
+
Avatar.generate(username, size)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.execute(cmd)
|
43
|
+
cmd = cmd.join(' ') if cmd.is_a?(Array)
|
44
|
+
cmd.tr!("'", '"') if Gem.win_platform?
|
45
|
+
|
46
|
+
_stdout_str, err = Open3.capture3(cmd)
|
47
|
+
if !err.nil? && !err.empty?
|
48
|
+
raise ExecutionError.new("letter_avatar execution error (when calling '#{cmd}'): '#{err.strip}'")
|
49
|
+
end
|
50
|
+
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.path_to_url(path)
|
55
|
+
path.to_s.sub('public/', '/')
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: letter_avatar_for7
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- xuling
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-11 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: clone of letter_avatar gem, but for imagemagick 7
|
14
|
+
email:
|
15
|
+
- flyxcat@outlook.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- CHANGELOG.md
|
21
|
+
- README.md
|
22
|
+
- Roboto-Medium
|
23
|
+
- lib/letter_avatar.rb
|
24
|
+
- lib/letter_avatar/avatar.rb
|
25
|
+
- lib/letter_avatar/avatar_helper.rb
|
26
|
+
- lib/letter_avatar/colors.rb
|
27
|
+
- lib/letter_avatar/configuration.rb
|
28
|
+
- lib/letter_avatar/has_avatar.rb
|
29
|
+
- lib/letter_avatar/version.rb
|
30
|
+
homepage: https://github.com/ksz2k/letter_avatar
|
31
|
+
licenses:
|
32
|
+
- MIT
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubygems_version: 3.5.22
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Create nice initals avatars from your users usernames
|
53
|
+
test_files: []
|