daily_image 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +26 -0
- data/README.md +96 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/daily_image +145 -0
- data/bin/setup +8 -0
- data/daily_image.gemspec +35 -0
- data/lib/daily_image/config.rb +49 -0
- data/lib/daily_image/image.rb +205 -0
- data/lib/daily_image/poem.rb +41 -0
- data/lib/daily_image/version.rb +3 -0
- data/lib/daily_image.rb +30 -0
- data/tmp/daily_2018-09-14.jpg +0 -0
- data/tmp/daily_2018-09-17.jpg +0 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1efdea98fc3b59bc85431e1c8384ce8d0095cc22ff54d11021ef6918df677ae3
|
4
|
+
data.tar.gz: 804765d2e0540898e7853407fb3a23bcd7cd51128b8d30e57cd5f24a8daed6f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 34ba4f064cb456f6747f40fb7355e5e8922612736ef322d3fa129911b4289144eee46df4b7185746f5bcb248ed260ed3c14d61189722e90c2ab27ea59333d461
|
7
|
+
data.tar.gz: 219c852823562df7adb6f7b59efb75c773fe030afeb4e6b1825db5227eafc6df0133e113902adc8975e15225975305f2a46cbdff0a27b3af11ebcffb6366cdda
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at lanyuejin1108@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
daily_image (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ffi (1.9.25)
|
10
|
+
minitest (5.11.3)
|
11
|
+
rake (10.5.0)
|
12
|
+
ruby-vips (2.0.13)
|
13
|
+
ffi (~> 1.9)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
bundler (~> 1.16)
|
20
|
+
daily_image!
|
21
|
+
minitest (~> 5.0)
|
22
|
+
rake (~> 10.0)
|
23
|
+
ruby-vips (~> 2.0.13)
|
24
|
+
|
25
|
+
BUNDLED WITH
|
26
|
+
1.16.1
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# DailyImage
|
2
|
+
|
3
|
+
日签 Or 日历,生成一张当日的图片。Just For Fun!👏
|
4
|
+
|
5
|
+
## 使用
|
6
|
+
|
7
|
+
如果需要在项目中使用,在你的gemfile中添加以下代码
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'daily_image'
|
11
|
+
```
|
12
|
+
|
13
|
+
然后执行下面的命令
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
或者,你可以直接安装使用
|
18
|
+
|
19
|
+
$ gem install daily_image
|
20
|
+
|
21
|
+
## 使用
|
22
|
+
|
23
|
+
### 配置使用
|
24
|
+
|
25
|
+
当你需要项目使用时,可以通过下面方式修改默认配置:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
|
29
|
+
# 初始项目配置
|
30
|
+
DailyImage.configure do |config|
|
31
|
+
config[:bg_color] = [255, 255, 255] # 背景颜色
|
32
|
+
config[:frame_color] = [151, 158, 160] # 边框颜色
|
33
|
+
config[:text_color] = [100, 145, 170] # 文字颜色
|
34
|
+
config[:date_color] = [100, 145, 170] # 中间日期颜色
|
35
|
+
config[:unused_color] = [200, 205, 215] # 进度条未使用颜色
|
36
|
+
config[:used_color] = [100, 145, 170] # 进度条已使用颜色
|
37
|
+
config[:out_frame_offset] = 15 # 外层边框偏移量
|
38
|
+
config[:in_frame_offset] = 50 # 下半部分内层边框偏移量
|
39
|
+
config[:font] = 'Hiragino Sans GB' # 文字默认字体
|
40
|
+
end
|
41
|
+
|
42
|
+
# 调用方法
|
43
|
+
DailyImage.draw_image(output_path) # 默认图片存放地址,包所在的目录
|
44
|
+
|
45
|
+
# 例子
|
46
|
+
DailyImage.draw_image('./')
|
47
|
+
```
|
48
|
+
|
49
|
+
### 命令行
|
50
|
+
|
51
|
+
如果是直接安装,可以通过命令行直接调用。**当然,还是需要安装ruby以及对应的依赖**
|
52
|
+
|
53
|
+
```shell
|
54
|
+
$ bundle exec daily_image -h
|
55
|
+
Usage: daily_image [options]
|
56
|
+
|
57
|
+
Specific options:
|
58
|
+
-b, --bg_color BG_COLOR the image's background color
|
59
|
+
-r, --frame_color FRAME_COLOR the image's frame color
|
60
|
+
-t, --text_color TEXT_COLOR the image's text color
|
61
|
+
-d, --date_color DATE_COLOR the middle date's text color
|
62
|
+
-n, --unused_color UNUSED_COLOR unused color of the progress bar
|
63
|
+
-u, --used_color USED_COLOR used color of the progress bar
|
64
|
+
-o OUT_FRAME_OFFSET, the outside frame offset
|
65
|
+
--out_offset
|
66
|
+
-i, --in_offset IN_FRAME_OFFSET the inside frame offset
|
67
|
+
-f, --font FONT the text font
|
68
|
+
-s, --output OUTPUT the output path, save the new image
|
69
|
+
|
70
|
+
Common options:
|
71
|
+
-h, --help Show the help message
|
72
|
+
-v, --version Show version
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
## 示例
|
77
|
+
|
78
|
+
![](./tmp/daily_2018-09-17.jpg)
|
79
|
+
|
80
|
+
## 感谢🙏
|
81
|
+
|
82
|
+
站在巨人的肩膀上
|
83
|
+
|
84
|
+
1. 画图使用了 [ruby-vips](https://github.com/jcupitt/ruby-vips)
|
85
|
+
|
86
|
+
2. 诗词来自于 [一言·古诗词 API](https://github.com/xenv/gushici)
|
87
|
+
|
88
|
+
## 如何贡献
|
89
|
+
|
90
|
+
1. Fork it
|
91
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
92
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
93
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
94
|
+
5. Create new Pull Request
|
95
|
+
|
96
|
+
欢迎贡献相关代码或是反馈使用时遇到的问题👏,另外请记得为你的代码编写测试。
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "daily_image"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/daily_image
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "optparse"
|
5
|
+
require "json"
|
6
|
+
require "daily_image"
|
7
|
+
|
8
|
+
class DailyImageOptparser
|
9
|
+
|
10
|
+
class Parser
|
11
|
+
attr_accessor :bg_color,
|
12
|
+
:frame_color,
|
13
|
+
:text_color,
|
14
|
+
:date_color,
|
15
|
+
:unused_color,
|
16
|
+
:used_color,
|
17
|
+
:font,
|
18
|
+
:out_frame_offset,
|
19
|
+
:in_frame_offset,
|
20
|
+
:output_path
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
end
|
24
|
+
|
25
|
+
def define_options(parser)
|
26
|
+
parser.banner = "Usage: daily_image [options]"
|
27
|
+
parser.separator ""
|
28
|
+
parser.separator "Specific options:"
|
29
|
+
|
30
|
+
bg_color_option(parser)
|
31
|
+
frame_color_option(parser)
|
32
|
+
text_color_option(parser)
|
33
|
+
date_color_option(parser)
|
34
|
+
unused_color_option(parser)
|
35
|
+
used_color_option(parser)
|
36
|
+
out_frame_offset_option(parser)
|
37
|
+
in_frame_offset_option(parser)
|
38
|
+
font_option(parser)
|
39
|
+
output_path_option(parser)
|
40
|
+
|
41
|
+
parser.separator ""
|
42
|
+
parser.separator "Common options:"
|
43
|
+
|
44
|
+
parser.on_tail("-h", "--help", "Show the help message") do
|
45
|
+
puts parser
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
# Another typical switch to print the version.
|
49
|
+
parser.on_tail("-v", "--version", "Show version") do
|
50
|
+
puts DailyImage::VERSION
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def bg_color_option(parser)
|
58
|
+
parser.on("-b", "--bg_color BG_COLOR", "the image's background color") do |bg_color|
|
59
|
+
self.bg_color = bg_color
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def frame_color_option(parser)
|
64
|
+
parser.on("-r", "--frame_color FRAME_COLOR", "the image's frame color") do |frame_color|
|
65
|
+
self.frame_color = frame_color
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def text_color_option(parser)
|
70
|
+
parser.on("-t", "--text_color TEXT_COLOR", "the image's text color") do |text_color|
|
71
|
+
self.text_color = text_color
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def date_color_option(parser)
|
76
|
+
parser.on("-d", "--date_color DATE_COLOR", "the middle date's text color") do |date_color|
|
77
|
+
self.date_color = date_color
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def unused_color_option(parser)
|
82
|
+
parser.on("-n", "--unused_color UNUSED_COLOR", "unused color of the progress bar") do |unused_color|
|
83
|
+
self.unused_color = unused_color
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def used_color_option(parser)
|
88
|
+
parser.on("-u", "--used_color USED_COLOR", "used color of the progress bar") do |used_color|
|
89
|
+
self.used_color = used_color
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def out_frame_offset_option(parser)
|
94
|
+
parser.on("-o", "--out_offset OUT_FRAME_OFFSET", "the outside frame offset") do |out_offset|
|
95
|
+
self.out_frame_offset = out_offset
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def in_frame_offset_option(parser)
|
100
|
+
parser.on("-i", "--in_offset IN_FRAME_OFFSET", "the inside frame offset") do |in_offset|
|
101
|
+
self.in_frame_offset = in_offset
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def font_option(parser)
|
106
|
+
parser.on("-f", "--font FONT", "the text font") do |font|
|
107
|
+
self.font = font
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def output_path_option(parser)
|
112
|
+
parser.on("-s", "--output OUTPUT", "the output path, save the new image") do |output|
|
113
|
+
self.output_path = output
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_reader :parser, :options
|
120
|
+
def parse(args)
|
121
|
+
@options = Parser.new
|
122
|
+
@args = OptionParser.new do |parser|
|
123
|
+
@options.define_options(parser)
|
124
|
+
parser.parse!(args)
|
125
|
+
end
|
126
|
+
@options
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
parser = DailyImageOptparser.new
|
131
|
+
options = parser.parse(ARGV)
|
132
|
+
|
133
|
+
DailyImage.configure do |config|
|
134
|
+
config.bg_color = JSON.parse(options.bg_color) if options.bg_color
|
135
|
+
config.frame_color = JSON.parse(options.frame_color) if options.frame_color
|
136
|
+
config.text_color = JSON.parse(options.text_color) if options.text_color
|
137
|
+
config.date_color = JSON.parse(options.date_color) if options.date_color
|
138
|
+
config.unused_color = JSON.parse(options.unused_color) if options.unused_color
|
139
|
+
config.used_color = JSON.parse(options.used_color) if options.used_color
|
140
|
+
config.out_frame_offset = options.out_frame_offset.to_i if options.out_frame_offset
|
141
|
+
config.in_frame_offset = options.in_frame_offset.to_i if options.in_frame_offset
|
142
|
+
config.font = options.font if options.font
|
143
|
+
end
|
144
|
+
|
145
|
+
DailyImage.draw_image(options.output_path)
|
data/bin/setup
ADDED
data/daily_image.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "daily_image/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "daily_image"
|
8
|
+
spec.version = DailyImage::VERSION
|
9
|
+
spec.authors = ["renyijiu"]
|
10
|
+
spec.email = ["lanyuejin1108@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A gem generate a daily image. Just For Fun 😊}
|
13
|
+
spec.description = %q{A gem generate a daily image. Just For Fun 😊}
|
14
|
+
spec.homepage = "https://github.com/renyijiu/daily_image"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
+
"public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
f.match(%r{^(test|spec|features)/})
|
27
|
+
end
|
28
|
+
spec.bindir = "bin"
|
29
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "singleton"
|
2
|
+
|
3
|
+
module DailyImage
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
# 背景颜色
|
8
|
+
attr_accessor :bg_color
|
9
|
+
|
10
|
+
# 边框颜色
|
11
|
+
attr_accessor :frame_color
|
12
|
+
|
13
|
+
# 文字颜色
|
14
|
+
attr_accessor :text_color
|
15
|
+
|
16
|
+
# 中间日期颜色
|
17
|
+
attr_accessor :date_color
|
18
|
+
|
19
|
+
# 进度条未使用颜色
|
20
|
+
attr_accessor :unused_color
|
21
|
+
|
22
|
+
# 进度条已使用颜色
|
23
|
+
attr_accessor :used_color
|
24
|
+
|
25
|
+
# 文字默认字体
|
26
|
+
attr_accessor :font
|
27
|
+
|
28
|
+
# 外层边框偏移量
|
29
|
+
attr_accessor :out_frame_offset
|
30
|
+
|
31
|
+
# 下半部分内层边框偏移量
|
32
|
+
attr_accessor :in_frame_offset
|
33
|
+
|
34
|
+
def configuration
|
35
|
+
@config ||= {}.tap do |config|
|
36
|
+
config[:bg_color] = bg_color || [255, 255, 255]
|
37
|
+
config[:frame_color] = frame_color || [151, 158, 160]
|
38
|
+
config[:text_color] = text_color || [100, 145, 170]
|
39
|
+
config[:date_color] = date_color || [100, 145, 170]
|
40
|
+
config[:unused_color] = unused_color || [200, 205, 215]
|
41
|
+
config[:used_color] = used_color || [100, 145, 170]
|
42
|
+
config[:out_frame_offset] = out_frame_offset || 15
|
43
|
+
config[:in_frame_offset] = in_frame_offset || 50
|
44
|
+
config[:font] = font || 'Hiragino Sans GB'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
|
2
|
+
module DailyImage
|
3
|
+
class Image
|
4
|
+
|
5
|
+
def initialize(width = 600, height = 800)
|
6
|
+
@width = width
|
7
|
+
@height = height
|
8
|
+
end
|
9
|
+
|
10
|
+
def draw_image
|
11
|
+
image = Vips::Image.black(@width, @height)
|
12
|
+
image = draw_top_half(image)
|
13
|
+
|
14
|
+
draw_down_half(image)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def config
|
20
|
+
@config ||= DailyImage.config
|
21
|
+
end
|
22
|
+
|
23
|
+
# 画出上半部分
|
24
|
+
def draw_top_half(image)
|
25
|
+
image = draw_background(image)
|
26
|
+
image = draw_frame(image)
|
27
|
+
image = draw_day(image)
|
28
|
+
image = draw_date(image)
|
29
|
+
image = draw_week(image)
|
30
|
+
image = draw_progress_txt(image)
|
31
|
+
|
32
|
+
draw_progress(image)
|
33
|
+
end
|
34
|
+
|
35
|
+
# 画出下半部分
|
36
|
+
def draw_down_half(image)
|
37
|
+
image = draw_down_frame(image)
|
38
|
+
|
39
|
+
draw_poem(image)
|
40
|
+
end
|
41
|
+
|
42
|
+
# 设置背景颜色
|
43
|
+
def draw_background(image)
|
44
|
+
image + config[:bg_color]
|
45
|
+
end
|
46
|
+
|
47
|
+
# 画出外边框
|
48
|
+
def draw_frame(image)
|
49
|
+
[0, 1, 2, 3, 4, 10, 11].each do |offset|
|
50
|
+
offset += config[:out_frame_offset]
|
51
|
+
|
52
|
+
width = @width - 2 * offset
|
53
|
+
height = @height - 2 * offset
|
54
|
+
|
55
|
+
image = image.draw_rect(config[:frame_color], offset, offset, width, height, fill: false)
|
56
|
+
end
|
57
|
+
|
58
|
+
image
|
59
|
+
end
|
60
|
+
|
61
|
+
# 画出中间日期
|
62
|
+
def draw_day(image)
|
63
|
+
day = Date.today.day.to_s
|
64
|
+
|
65
|
+
# 生成字体图片
|
66
|
+
text = generate_text_image(day, dpi: 1000, text_color: config[:date_color])
|
67
|
+
|
68
|
+
# 计算字体放置位置
|
69
|
+
x = (image.width - text.width) / 2
|
70
|
+
y = (image.height * 0.2).to_i
|
71
|
+
|
72
|
+
image.draw_image text, x, y, mode: :set
|
73
|
+
end
|
74
|
+
|
75
|
+
# 画出左上角日期
|
76
|
+
def draw_date(image)
|
77
|
+
date = Date.today.to_s
|
78
|
+
text = generate_text_image(date, dpi: 150)
|
79
|
+
|
80
|
+
# 计算放置位置
|
81
|
+
x = (image.width * 0.1).to_i
|
82
|
+
y = (image.height * 0.09).to_i
|
83
|
+
|
84
|
+
image.draw_image text, x, y, mode: :set
|
85
|
+
end
|
86
|
+
|
87
|
+
# 画出右上角信息
|
88
|
+
def draw_week(image)
|
89
|
+
week_arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
90
|
+
week = week_arr[Date.today.cwday]
|
91
|
+
|
92
|
+
text = generate_text_image(week, dpi: 140)
|
93
|
+
|
94
|
+
# 计算放置位置
|
95
|
+
x = (image.width * 0.75).to_i
|
96
|
+
y = (image.height * 0.09).to_i
|
97
|
+
|
98
|
+
image.draw_image text, x, y, mode: :set
|
99
|
+
end
|
100
|
+
|
101
|
+
# 画出进度描述信息
|
102
|
+
def draw_progress_txt(image)
|
103
|
+
day = Date.today.yday
|
104
|
+
percent = (percent_of_year * 100).round(2)
|
105
|
+
text = "第 #{day} 天,进度已消耗 #{percent}%"
|
106
|
+
|
107
|
+
# 获取文字图片
|
108
|
+
text_image = generate_text_image(text)
|
109
|
+
|
110
|
+
x = (@width - text_image.width) / 2
|
111
|
+
y = @height * 0.44
|
112
|
+
|
113
|
+
image.draw_image text_image, x, y, mode: :set
|
114
|
+
end
|
115
|
+
|
116
|
+
# 画出年进度信息
|
117
|
+
def draw_progress(image)
|
118
|
+
height = 30
|
119
|
+
|
120
|
+
unused_width = @width - 2 * config[:in_frame_offset]
|
121
|
+
used_width = (unused_width * percent_of_year).to_i
|
122
|
+
|
123
|
+
x = config[:in_frame_offset]
|
124
|
+
y = (@height * 0.5).to_i
|
125
|
+
|
126
|
+
# 画出整年的进度条
|
127
|
+
image = image.draw_rect(config[:unused_color], x, y, unused_width, height, fill: true)
|
128
|
+
|
129
|
+
# 画出已进行的进度条
|
130
|
+
image.draw_rect(config[:used_color], x, y, used_width, height, fill: true)
|
131
|
+
end
|
132
|
+
|
133
|
+
# 画出下半部分边框
|
134
|
+
def draw_down_frame(image)
|
135
|
+
width = (@width - 2 * config[:in_frame_offset]).to_i
|
136
|
+
height = (@height * 0.49 - 2 * config[:in_frame_offset]).to_i
|
137
|
+
|
138
|
+
x = config[:in_frame_offset]
|
139
|
+
y = (@height * 0.51 + config[:in_frame_offset]).to_i
|
140
|
+
|
141
|
+
image.draw_rect(config[:frame_color], x, y, width, height, fill: false)
|
142
|
+
end
|
143
|
+
|
144
|
+
def draw_poem(image)
|
145
|
+
_, res = DailyImage::Poem.new.txt
|
146
|
+
|
147
|
+
title = res['origin'] || '无题'
|
148
|
+
content = res['content'] || '唯有梦想与爱情,不可辜负。'
|
149
|
+
author = "--- #{res['author'] || '佚名'}"
|
150
|
+
|
151
|
+
image = draw_poem_title(image, title)
|
152
|
+
image = draw_poem_content(image, content)
|
153
|
+
draw_poem_author(image, author)
|
154
|
+
end
|
155
|
+
|
156
|
+
def draw_poem_title(image, title)
|
157
|
+
text = generate_text_image(title, dpi: 110)
|
158
|
+
|
159
|
+
x = ((@width - text.width) / 2).to_i
|
160
|
+
y = (@height * 0.65).to_i
|
161
|
+
|
162
|
+
image.draw_image text, x, y, mode: :set
|
163
|
+
end
|
164
|
+
|
165
|
+
def draw_poem_content(image, content)
|
166
|
+
text = generate_text_image(content, dpi: 135)
|
167
|
+
|
168
|
+
x = ((@width - text.width) / 2).to_i
|
169
|
+
y = (@height * 0.75).to_i
|
170
|
+
|
171
|
+
image.draw_image text, x, y, mode: :set
|
172
|
+
end
|
173
|
+
|
174
|
+
def draw_poem_author(image, author)
|
175
|
+
text = generate_text_image(author)
|
176
|
+
|
177
|
+
x = (@width - text.width - config[:in_frame_offset] - 10).to_i
|
178
|
+
y = (@height * 0.85).to_i
|
179
|
+
|
180
|
+
image.draw_image text, x, y, mode: :set
|
181
|
+
end
|
182
|
+
|
183
|
+
# 计算当天时间在一年的百分比
|
184
|
+
def percent_of_year
|
185
|
+
days = Date.new(Date.today.year, 12, 31).yday
|
186
|
+
current_days = Date.today.yday
|
187
|
+
|
188
|
+
(current_days.to_f / days).round(4)
|
189
|
+
end
|
190
|
+
|
191
|
+
# 生成字体图片
|
192
|
+
def generate_text_image(text, opts={})
|
193
|
+
dpi = opts.fetch(:dpi, 100)
|
194
|
+
text_color = opts.fetch(:text_color, config[:text_color])
|
195
|
+
bg_color = opts.fetch(:bg_color, config[:bg_color])
|
196
|
+
font = opts.fetch(:font, config[:font])
|
197
|
+
|
198
|
+
text_image = Vips::Image.text text, dpi: dpi, font: font
|
199
|
+
text_image = text_image.embed 0, 0, text_image.width, text_image.height, extend: :mirror
|
200
|
+
|
201
|
+
text_image.ifthenelse(text_color, bg_color, blend: true)
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
#
|
5
|
+
# 使用 一言·古诗词 API, 获取一条古诗词
|
6
|
+
#
|
7
|
+
# API返回结果:
|
8
|
+
# {
|
9
|
+
# content: "陌上风光浓处。第一寒梅先吐。",
|
10
|
+
# origin: "十样花·陌上风光浓处",
|
11
|
+
# author: "李弥逊",
|
12
|
+
# category: "古诗文-植物-梅花"
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
module DailyImage
|
16
|
+
class Poem
|
17
|
+
|
18
|
+
API_URL = "https://api.gushi.ci/all.json"
|
19
|
+
|
20
|
+
def txt
|
21
|
+
get(API_URL)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def get(url, params={})
|
27
|
+
uri = URI(url)
|
28
|
+
uri.query = URI.encode_www_form(params)
|
29
|
+
|
30
|
+
res = Net::HTTP.get_response(uri)
|
31
|
+
format_res(res)
|
32
|
+
end
|
33
|
+
|
34
|
+
def format_res(res)
|
35
|
+
return [false, {}] unless res.is_a?(Net::HTTPSuccess)
|
36
|
+
|
37
|
+
[true, JSON.parse(res.body)]
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/daily_image.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "date"
|
2
|
+
require "vips"
|
3
|
+
require "daily_image/version"
|
4
|
+
require "daily_image/poem"
|
5
|
+
require "daily_image/image"
|
6
|
+
require "daily_image/config"
|
7
|
+
|
8
|
+
module DailyImage
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def configure
|
12
|
+
config = DailyImage::Config.instance
|
13
|
+
yield config
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
DailyImage::Config.instance.configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw_image(output_path = nil)
|
21
|
+
output_path ||= Dir.pwd
|
22
|
+
output_file = File.join(output_path, "daily_#{Date.today}.jpeg")
|
23
|
+
|
24
|
+
image = DailyImage::Image.new.draw_image
|
25
|
+
|
26
|
+
image.write_to_file(output_file, Q: 100)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
Binary file
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: daily_image
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- renyijiu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
description: "A gem generate a daily image. Just For Fun \U0001F60A"
|
56
|
+
email:
|
57
|
+
- lanyuejin1108@gmail.com
|
58
|
+
executables:
|
59
|
+
- console
|
60
|
+
- daily_image
|
61
|
+
- setup
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- ".gitignore"
|
66
|
+
- ".travis.yml"
|
67
|
+
- CODE_OF_CONDUCT.md
|
68
|
+
- Gemfile
|
69
|
+
- Gemfile.lock
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- bin/console
|
73
|
+
- bin/daily_image
|
74
|
+
- bin/setup
|
75
|
+
- daily_image.gemspec
|
76
|
+
- lib/daily_image.rb
|
77
|
+
- lib/daily_image/config.rb
|
78
|
+
- lib/daily_image/image.rb
|
79
|
+
- lib/daily_image/poem.rb
|
80
|
+
- lib/daily_image/version.rb
|
81
|
+
- tmp/daily_2018-09-14.jpg
|
82
|
+
- tmp/daily_2018-09-17.jpg
|
83
|
+
homepage: https://github.com/renyijiu/daily_image
|
84
|
+
licenses: []
|
85
|
+
metadata:
|
86
|
+
allowed_push_host: https://rubygems.org
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.7.6
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: "A gem generate a daily image. Just For Fun \U0001F60A"
|
107
|
+
test_files: []
|