catpix 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fcdff6dbde407d1a3da16b3a1d938175e93e9f0e
4
- data.tar.gz: 0fd1b98ca31f31aceb50ddc3b287f584cec30cac
3
+ metadata.gz: 196bc701b3b4f11b7e85b6f2b7280c0fba468fb0
4
+ data.tar.gz: 24b01ca8de6cf965dc93c41298335bf67a71b513
5
5
  SHA512:
6
- metadata.gz: 426b64e05e95359d8fbd0e75ef17b077cac04710bb6507dee5fcd95117748bddb65499d2a192de2766ef8b38c2797ce9b17ad9de04aad99f6f8cc1bcfefd2084
7
- data.tar.gz: abbf23e0c4a5de5e83288339b0203302952e3f539943d22245992d22ca4d2de1ddb3b6af91fa0269df6ec241f1835efec7ea885f20bea5defe1b63d8afd393c6
6
+ metadata.gz: fdbb8c571854223d2516906e59845ddbc6f1e8c218e8a43313031bcb98134038e6fb152e2aa3ddeb8a54b401521ffbd3dd0fe6a0335e7715b39b93244f176c6b
7
+ data.tar.gz: 1577dc3ecf67e30f69ba406dc442e0aee02348aeff2e1739e18b8c67c6507a4454a164563dfeed75288b0856ed75751e61c91cf317152b90f023b54bd3ce21b7
@@ -0,0 +1,7 @@
1
+ ## 0.2.0 (2015-07-04)
2
+
3
+ New features:
4
+
5
+ - Quadrupled the resolution of the image
6
+ - Added line buffering
7
+ - Drawing margins is slightly quicker
data/README.md CHANGED
@@ -1,10 +1,98 @@
1
1
  # Catpix
2
2
 
3
- TODO: Write a gem description
3
+ [![Gem Version](https://badge.fury.io/rb/catpix.png)](http://badge.fury.io/rb/catpix)
4
+ [![Inline docs](http://inch-ci.org/github/pazdera/catpix.png)](http://inch-ci.org/github/pazdera/catpix)
5
+
6
+ Renders images in the terminal.
7
+
8
+ ![Pokemon](http://radek.io/assets/images/posts/catpix/pokemon.png)
9
+
10
+ It will handle most image formats (png, jpg, gif, bpm and many more). As long
11
+ as ImageMagick can read it, catpix can too. By default, it will scale them
12
+ down to fit the width of your terminal. You can set the same for the height
13
+ of the image and also center it by providing custom options (see Usage below).
14
+
15
+ On the inside, catpix uses [rmagick](https://rubygems.org/gems/rmagick) to read
16
+ and scale images and the [tco](https://github.com/pazdera/tco) gem to map its
17
+ colours to the extended 256 colour palette in the terminal. A pixel is
18
+ approximated as two spaces, so you might get weird results in case your font
19
+ has different proportions.
20
+
21
+ It can render full resolution photos, although it takes a while and the
22
+ resolution is obviously limited. Here's a photo of some flowers in my window,
23
+ straight from my phone and rendered in the terminal:
24
+
25
+ ![Full photo](http://radek.io/assets/images/posts/catpix/photo.png)
26
+
27
+ ### Resolutions (new in 0.2.0)
28
+
29
+ Catpix can render images in two resolutions. If you terminal supports
30
+ unicode, it will use the
31
+ [upper half block](http://www.fileformat.info/info/unicode/char/2580/index.htm)
32
+ to dispplay one pixel. Otherwise, a pixel will be approximated as two
33
+ spaces. The detection is automatic, but you can also force one or the
34
+ other via _options_. The higher setting has four times as many pixels as the
35
+ lower one. See how do they compare below:
36
+
37
+ ![Comparing resolutions](http://radek.io/assets/images/posts/catpix/resolution.gif)
4
38
 
5
39
  ## Usage
6
40
 
7
- TODO: Write usage instructions here
41
+ ### In the terminal
42
+
43
+ The gem will install the `catpix` command on your system that you can use
44
+ directly from shell. To print an image simply pass the path to it as the
45
+ first argument:
46
+
47
+ $ catpix pokemon.gif
48
+
49
+ Use the `-c` flag to center it (x for horizontal and y for vertical centering):
50
+
51
+ $ catpix panda.png -c xy
52
+
53
+ Add `-w` or `-h` to scale it down. These two options require a factor of the
54
+ size of your terminal. If you want to limit the size of your image to half of
55
+ your terminal window use:
56
+
57
+ $ catpix trophy.png -w 0.5 -h 0.5
58
+
59
+ And finally, if your image has any fully transparent pixels, you can specify
60
+ background colour to be rendered behind and around the image. Use `-b` to
61
+ specify the colour and `-f` to make it fill the margins around the image if
62
+ it's centered:
63
+
64
+ $ catpix tux.png -b "#00ff00" # RGB is fine
65
+ $ catpix tux.png -b green # tco aliases work too
66
+ $ catpix tux.png -c xy -b green -f # fill the margins around the image too
67
+ $ catpix tux.png -c xy -r high # enforce high resolution
68
+
69
+ ### In Ruby
70
+
71
+ The Ruby API consists of only a single function called `print_image`:
72
+
73
+ ```ruby
74
+ require 'catpix'
75
+
76
+ Catpix::print_image "pokemon.png",
77
+ :limit_x => 1.0,
78
+ :limit_y => 0,
79
+ :center_x => true,
80
+ :center_y => true,
81
+ :bg => "white",
82
+ :bg_fill => true,
83
+ :resolution => low
84
+ ```
85
+
86
+ See the [documentation at RubyDoc](http://www.rubydoc.info/github/pazdera/catpix/master/Catpix.print_image)
87
+ for more detail.
88
+
89
+ ## More examples
90
+
91
+ ![UK Flag](http://radek.io/assets/images/posts/catpix/flag.png)
92
+
93
+ ![Happy Panda](http://radek.io/assets/images/posts/catpix/panda.png)
94
+
95
+ ![Trophy](http://radek.io/assets/images/posts/catpix/trophy.png)
8
96
 
9
97
  ## Installation
10
98
 
@@ -21,6 +109,9 @@ And then execute:
21
109
 
22
110
  $ bundle
23
111
 
112
+ ## Author
113
+
114
+ Radek Pazdera <me@radek.io> [radek.io](http://radek.io/)
24
115
 
25
116
  ## Contributing
26
117
 
data/bin/catpix CHANGED
@@ -21,6 +21,7 @@ Options:
21
21
  -c=<pos>, --center Set x, y or xy centering in the window.
22
22
  -b=<colour>, --bg Set background colour.
23
23
  -f, --bg-fill Draw background around the image as well.
24
+ -r=<res>, --resolution Either 'high' or 'low' [default: auto].
24
25
 
25
26
  --help Show this message.
26
27
  --version Print the version.
@@ -36,7 +37,8 @@ end
36
37
  options = {
37
38
  :limit_x => args['--limit-width'].to_f,
38
39
  :limit_y => args['--limit-height'].to_f,
39
- :bg_fill => args['--bg-fill']
40
+ :bg_fill => args['--bg-fill'],
41
+ :resolution => args['--resolution']
40
42
  }
41
43
 
42
44
  if args['--center']
@@ -21,7 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_dependency "tco", "~> 0.1", ">= 0.1.6"
24
+ spec.required_ruby_version = ">= 1.9"
25
+
26
+ spec.add_dependency "tco", "~> 0.1", ">= 0.1.8"
25
27
  spec.add_dependency "rmagick", "~> 2.15", ">= 2.15.2"
26
28
  spec.add_dependency "docopt", "~> 0.5", ">= 0.5.0"
27
29
  spec.add_dependency "ruby-terminfo", "~> 0.1", ">= 0.1.1"
@@ -41,38 +41,30 @@ module Catpix
41
41
  # alias 'red' or 'blue'. [default: nil]
42
42
  # @option options [Boolean] :bg_fill Fill the margins around the image with
43
43
  # background colour. [default: false]
44
+ # @option options [String] :resolution Determines the pixel size of the
45
+ # rendered image. Can be set to `high`,
46
+ # `low` or `auto` (default). If set to
47
+ # `auto` the resolution will be picked
48
+ # automatically based on your terminal's
49
+ # support of unicode.
44
50
  def self.print_image(path, options={})
45
51
  options = default_options.merge! options
46
52
 
53
+ if options[:resolution] == 'auto'
54
+ options[:resolution] = can_use_utf8? ? 'high' : 'low'
55
+ end
56
+ @@resolution = options[:resolution]
57
+
47
58
  img = load_image path
48
59
  resize! img, options[:limit_x], options[:limit_y]
49
60
 
50
61
  margins = get_margins img, options[:center_x], options[:center_y]
51
- margin_colour = options[:bg_fill] ? options[:bg] : nil
52
-
53
- print_vert_margin margins[:top], margin_colour
54
-
55
- # print left margin for the first row
56
- print_horiz_margin margins[:left], margin_colour
62
+ margins[:colour] = options[:bg_fill] ? options[:bg] : nil
57
63
 
58
- # print the image
59
- img.each_pixel do |pixel, col, row|
60
- if pixel.opacity == 65535
61
- print_pixel options[:bg]
62
- else
63
- print_pixel get_normal_rgb pixel
64
- end
65
-
66
- if col >= img.columns - 1
67
- print_horiz_margin margins[:right], margin_colour
68
- puts
69
-
70
- unless row == img.rows - 1
71
- print_horiz_margin margins[:left], margin_colour
72
- end
73
- end
64
+ if high_res?
65
+ do_print_image_hr img, margins, options
66
+ else
67
+ do_print_image_lr img, margins, options
74
68
  end
75
-
76
- print_vert_margin margins[:bottom], margin_colour
77
69
  end
78
70
  end
@@ -7,38 +7,76 @@ require "terminfo"
7
7
 
8
8
  module Catpix
9
9
  private
10
+ MAX_OPACITY = 65535
11
+
10
12
  def self.default_options
11
13
  {
12
- :limit_x => 1.0,
13
- :limit_y => 0,
14
- :center_x => false,
15
- :center_y => false,
16
- :bg => nil,
17
- :bg_fill => false
14
+ limit_x: 1.0,
15
+ limit_y: 0,
16
+ center_x: false,
17
+ center_y: false,
18
+ bg: nil,
19
+ bg_fill: false,
20
+ resolution: 'auto'
18
21
  }
19
22
  end
20
23
 
21
- def self.print_pixel(colour=nil)
22
- if colour
23
- print " ".bg colour
24
- else
25
- print " "
24
+ @@resolution = nil
25
+
26
+ def self.high_res?
27
+ @@resolution == 'high'
28
+ end
29
+
30
+ def self.can_use_utf8?
31
+ ENV.values_at("LC_ALL", "LC_CTYPE", "LANG").compact.first.include?("UTF-8")
32
+ end
33
+
34
+ def self.prep_lr_pixel(colour)
35
+ colour ? " ".bg(colour) : " "
36
+ end
37
+
38
+ def self.print_lr_pixel(colour)
39
+ print prep_lr_pixel colour
40
+ end
41
+
42
+ def self.prep_hr_pixel(colour_top, colour_bottom)
43
+ upper = "\u2580"
44
+ lower = "\u2584"
45
+
46
+ return " " if colour_bottom.nil? and colour_top.nil?
47
+ return lower.fg colour_bottom if colour_top.nil?
48
+ return upper.fg colour_top if colour_bottom.nil?
49
+
50
+ c_top = Tco::match_colour colour_top
51
+ c_bottom = Tco::match_colour colour_bottom
52
+ if c_top == c_bottom
53
+ return " ".bg "@#{c_top}"
26
54
  end
55
+
56
+ upper.fg("@#{c_top}").bg("@#{c_bottom}")
57
+ end
58
+
59
+ def self.print_hr_pixel(colour_top, colour_bottom)
60
+ print prep_hr_pixel colour_top, colour_bottom
27
61
  end
28
62
 
29
63
  # Returns normalised size of the terminal window
30
64
  #
31
- # Catpix uses two blank characters to approximate pixels in the terminal,
32
- # so we need to divide the width of the terminal by 2.
65
+ # Catpix can use either two blank spaces to approximate a pixel in the
66
+ # temrinal or the 'upper half block' and 'bottom half block' characters.
67
+ #
68
+ # Depending on which of the above will be used, the screen size
69
+ # must be normalised accordingly.
33
70
  def self.get_screen_size
34
71
  th, tw = TermInfo.screen_size
35
- [tw / 2, th]
72
+ if high_res? then [tw, th * 2] else [tw / 2, th] end
36
73
  end
37
74
 
38
75
  def self.load_image(path)
39
76
  Magick::Image::read(path).first
40
77
  end
41
78
 
79
+ # Scale the image down based on the limits while keeping the aspect ratio
42
80
  def self.resize!(img, limit_x=0, limit_y=0)
43
81
  tw, th = get_screen_size
44
82
  iw = img.columns
@@ -58,8 +96,8 @@ module Catpix
58
96
 
59
97
  # Resize the image if it's bigger than the limited viewport
60
98
  if iw > width or ih > height
61
- img.change_geometry "#{width}x#{height}" do |cols, rows, img|
62
- img.resize! (cols).to_i, (rows).to_i
99
+ img.change_geometry "#{width}x#{height}" do |cols, rows, img_handle|
100
+ img_handle.resize! (cols).to_i, (rows).to_i
63
101
  end
64
102
  end
65
103
  end
@@ -92,18 +130,94 @@ module Catpix
92
130
  margins[:bottom] = 0
93
131
  end
94
132
 
133
+ if high_res? and margins[:top] % 2 and margins[:bottom] % 2
134
+ margins[:top] -= 1
135
+ margins[:bottom] += 1
136
+ end
137
+
95
138
  margins
96
139
  end
97
140
 
98
- def self.print_vert_margin(size, colour)
141
+ def self.prep_vert_margin(size, colour)
99
142
  tw, th = get_screen_size
100
- size.times do
101
- tw.times { print_pixel colour }
102
- puts
143
+
144
+ buffer = ""
145
+ if high_res?
146
+ (size / 2).times do
147
+ sub_buffer = ""
148
+ tw.times { sub_buffer += prep_hr_pixel nil, nil }
149
+ buffer += sub_buffer.bg(colour) + "\n"
150
+ end
151
+ else
152
+ size.times do
153
+ sub_buffer = ""
154
+ tw.times { sub_buffer += prep_lr_pixel nil }
155
+ buffer += sub_buffer.bg(colour) + "\n"
156
+ end
157
+ end
158
+ buffer
159
+ end
160
+
161
+ def self.prep_horiz_margin(size, colour)
162
+ buffer = ""
163
+ if high_res?
164
+ size.times { buffer += prep_hr_pixel nil, nil }
165
+ else
166
+ size.times { buffer += prep_lr_pixel nil }
167
+ end
168
+ buffer.bg colour
169
+ end
170
+
171
+ # Print the image in low resolution
172
+ def self.do_print_image_lr(img, margins, options)
173
+ print prep_vert_margin margins[:top], margins[:colour]
174
+
175
+ 0.upto(img.rows - 1) do |row|
176
+ buffer = prep_horiz_margin margins[:left], margins[:colour]
177
+ 0.upto(img.columns - 1) do |col|
178
+ pixel = img.pixel_color col, row
179
+
180
+ buffer += if pixel.opacity == MAX_OPACITY
181
+ prep_lr_pixel options[:bg]
182
+ else
183
+ prep_lr_pixel get_normal_rgb pixel
184
+ end
185
+ end
186
+ buffer += prep_horiz_margin margins[:right], margins[:colour]
187
+ puts buffer
103
188
  end
189
+
190
+ print prep_vert_margin margins[:bottom], margins[:colour]
104
191
  end
105
192
 
106
- def self.print_horiz_margin(size, colour)
107
- size.times { print_pixel colour }
193
+ # Print the image in high resolution (using unicode's upper half block)
194
+ def self.do_print_image_hr(img, margins, options)
195
+ print prep_vert_margin margins[:top], margins[:colour]
196
+
197
+ 0.step(img.rows - 1, 2) do |row|
198
+ # line buffering makes it about 20% faster
199
+ buffer = prep_horiz_margin margins[:left], margins[:colour]
200
+ 0.upto(img.columns - 1) do |col|
201
+ top_pixel = img.pixel_color col, row
202
+ colour_top = if top_pixel.opacity < MAX_OPACITY
203
+ get_normal_rgb top_pixel
204
+ else
205
+ options[:bg]
206
+ end
207
+
208
+ bottom_pixel = img.pixel_color col, row + 1
209
+ colour_bottom = if bottom_pixel.opacity < MAX_OPACITY
210
+ get_normal_rgb bottom_pixel
211
+ else
212
+ options[:bg]
213
+ end
214
+
215
+ buffer += prep_hr_pixel colour_top, colour_bottom
216
+ end
217
+ buffer += prep_horiz_margin margins[:right], margins[:colour]
218
+ puts buffer
219
+ end
220
+
221
+ print prep_vert_margin margins[:bottom], margins[:colour]
108
222
  end
109
223
  end
@@ -3,5 +3,5 @@
3
3
 
4
4
  module Catpix
5
5
  # Version of the gem
6
- VERSION = "0.1.1"
6
+ VERSION = "0.2.0"
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: catpix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radek Pazdera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-28 00:00:00.000000000 Z
11
+ date: 2015-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tco
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '0.1'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.1.6
22
+ version: 0.1.8
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '0.1'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.1.6
32
+ version: 0.1.8
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rmagick
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -131,6 +131,7 @@ extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
133
  - ".gitignore"
134
+ - CHANGELOG.md
134
135
  - Gemfile
135
136
  - LICENSE.txt
136
137
  - README.md
@@ -152,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
153
  requirements:
153
154
  - - ">="
154
155
  - !ruby/object:Gem::Version
155
- version: '0'
156
+ version: '1.9'
156
157
  required_rubygems_version: !ruby/object:Gem::Requirement
157
158
  requirements:
158
159
  - - ">="