meme_captain 0.1.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +8 -0
  3. data/ChangeLog +18 -0
  4. data/Gemfile +1 -1
  5. data/README.md +3 -45
  6. data/Rakefile +38 -0
  7. data/lib/meme_captain.rb +0 -6
  8. data/lib/meme_captain/caption.rb +10 -5
  9. data/lib/meme_captain/caption_choice.rb +3 -1
  10. data/lib/meme_captain/image_list.rb +0 -5
  11. data/lib/meme_captain/image_list/watermark.rb +1 -1
  12. data/lib/meme_captain/meme.rb +6 -2
  13. data/lib/meme_captain/memebg.rb +1 -1
  14. data/lib/meme_captain/text_pos.rb +9 -7
  15. data/lib/meme_captain/version.rb +1 -1
  16. data/meme_captain.gemspec +6 -17
  17. data/spec/assets/Coda-Heavy.ttf +0 -0
  18. data/spec/assets/me_gusta.png +0 -0
  19. data/spec/assets/otter.gif +0 -0
  20. data/spec/assets/town_crier.jpg +0 -0
  21. data/spec/caption_choice_spec.rb +4 -4
  22. data/spec/caption_spec.rb +22 -13
  23. data/spec/meme_captain_spec.rb +15 -1
  24. data/spec/memebg_spec.rb +2 -2
  25. data/spec/text_pos_spec.rb +11 -11
  26. metadata +38 -207
  27. data/config.ru +0 -50
  28. data/doc/lightweight_front_end.md +0 -64
  29. data/doc/setup.md +0 -13
  30. data/lib/meme_captain/image_list/cache.rb +0 -49
  31. data/lib/meme_captain/image_list/fetch.rb +0 -28
  32. data/lib/meme_captain/image_list/fetch_error.rb +0 -17
  33. data/lib/meme_captain/image_list/source_image.rb +0 -30
  34. data/lib/meme_captain/meme_data.rb +0 -33
  35. data/lib/meme_captain/norm_params.rb +0 -92
  36. data/lib/meme_captain/pretty_format.rb +0 -12
  37. data/lib/meme_captain/server.rb +0 -303
  38. data/lib/meme_captain/source_fetch_fail.rb +0 -28
  39. data/lib/meme_captain/upload.rb +0 -30
  40. data/public/css/screen.css +0 -80
  41. data/public/favicon.ico +0 -0
  42. data/public/js/fabric.min.js +0 -4
  43. data/public/js/jquery-1.7.2.min.js +0 -4
  44. data/public/js/meme_captain.js +0 -391
  45. data/public/source_images.json +0 -234
  46. data/public/thumbs.jpg +0 -0
  47. data/public/thumbs_1330486916.jpg +0 -0
  48. data/public/thumbs_1333591668.jpg +0 -0
  49. data/public/thumbs_1334189407.jpg +0 -0
  50. data/public/thumbs_1334973608.jpg +0 -0
  51. data/public/thumbs_1336623277.jpg +0 -0
  52. data/public/thumbs_1336624196.jpg +0 -0
  53. data/public/thumbs_1339811279.jpg +0 -0
  54. data/public/tmp/.gitignore +0 -0
  55. data/script/thumb_sprites.rb +0 -76
  56. data/spec/image_list/fetch_spec.rb +0 -33
  57. data/spec/norm_params_spec.rb +0 -223
  58. data/spec/pretty_format_spec.rb +0 -9
  59. data/views/404.erb +0 -17
  60. data/views/index.erb +0 -130
  61. data/watermark.png +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5edd684be8bf3e4e16efc36df7fc1bc0e0b586b49bf37fc986e0c1a9a655a534
4
+ data.tar.gz: 9d6f38081c90df4b2c54e9db68d56422c40faf83669a6a566d69a568053abda6
5
+ SHA512:
6
+ metadata.gz: 8cff67ab31b784d57e71c86cd2d3348f177749e6dd7bcfe6f4dfe517e3aa3cd8cae3e6b6e6c5882c211160ce372b14d427b7e521e3ad9a978f9f4abb8545ef37
7
+ data.tar.gz: 8c21d18d78a18b6b0890ef3ecf154f6d4930f099c8c33a06bf1ca3ead3a510e61559289da7679eb65a0210a5c5489c3000c99fb269d526395ea74fdead36e26f
@@ -0,0 +1,8 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.10
5
+ - 2.5.8
6
+ - 2.6.6
7
+ - 2.7.1
8
+ sudo: false
data/ChangeLog CHANGED
@@ -1,3 +1,21 @@
1
+ 0.3.0 2013-06-25
2
+
3
+ Move Sinatra web application to meme_captain_web_v1 repo.
4
+
5
+ 0.2.0 2013-06-10
6
+
7
+ Blur stroke.
8
+
9
+ 0.1.3 2013-06-06
10
+
11
+ Default super_sample to 1.0.
12
+
13
+ Add sample generator rake task.
14
+
15
+ Add travis ci and code climate.
16
+
17
+ Fix rubygems source.
18
+
1
19
  0.1.1 2012-04-26
2
20
 
3
21
  Update jQuery and fabric.js to latest versions.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Build Status](https://travis-ci.org/mmb/meme_captain.png)](https://travis-ci.org/mmb/meme_captain)
2
+ [![Code Climate](https://codeclimate.com/github/mmb/meme_captain.png)](https://codeclimate.com/github/mmb/meme_captain)
3
+
1
4
  Ruby gem to create meme images (images with text added).
2
5
 
3
6
  Runs locally and has no web dependencies.
@@ -42,48 +45,3 @@ Text box sizes and positions can be specified as pixels (the origin is the top
42
45
  left corner of the image) or as floats which are percentages of the image
43
46
  width and height. The x and y coordinates of a text box are the coordinates
44
47
  of its top left corner.
45
-
46
- Also includes a Sinatra app that exposes the API over HTTP which is currently
47
- running http://memecaptain.com/
48
-
49
- You can use the memecaptain.com API if you prefer it to using the gem.
50
-
51
- Simplest API:
52
-
53
- ```
54
- http://memecaptain.com/i?u=<url encoded source image url>&t1=<url encoded top text>&t2=<url encoded bottom text>
55
- ```
56
-
57
- Example:
58
-
59
- ```
60
- http://memecaptain.com/i?u=http%3A%2F%2Fmemecaptain.com%2Fyao_ming.jpg&t1=sure+i%27ll+test&t2=the+api
61
- ```
62
-
63
- ![Sure I'll test the API](http://memecaptain.com/i?u=http%3A%2F%2Fmemecaptain.com%2Fyao_ming.jpg&t1=sure+i%27ll+test&t2=the+api)
64
-
65
- If you want better error messages, use this which will return JSON:
66
-
67
- ```
68
- http://memecaptain.com/g?u=<url encoded source image url>&t1=<url encoded top text>&t2=<url encoded bottom text>
69
- ```
70
-
71
- Example:
72
-
73
- ```
74
- http://memecaptain.com/g?u=http%3A%2F%2Fmemecaptain.com%2Fyao_ming.jpg&t1=sure+i%27ll+test&t2=the+api
75
- ```
76
-
77
- ```json
78
- {
79
- imageUrl: "http://memecaptain.com/c7757f.jpg",
80
- templateUrl: "http://memecaptain.com/?u=c7757f.jpg"
81
- }
82
- ```
83
-
84
- Optional parameters t1x, t1y, t1w, t1h, t2x, t2y, t2w, t2h can be added to
85
- position and size text (see example above).
86
-
87
- If you want to host a customized version of the memecaptain.com web interface
88
- on your own web server but use the memecaptain.com backend see
89
- [lightweight front end](https://github.com/mmb/meme_captain/blob/master/doc/lightweight_front_end.md).
@@ -0,0 +1,38 @@
1
+ require 'tempfile'
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ require 'meme_captain'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :default => :spec
10
+
11
+ desc 'Generate various sample memes and open them in a browser'
12
+ task 'sample' do
13
+ source_images = {
14
+ gif: File.read(File.join(%w{spec assets otter.gif})),
15
+ jpg: File.read(File.join(%w{spec assets town_crier.jpg})),
16
+ png: File.read(File.join(%w{spec assets me_gusta.png})),
17
+ }
18
+
19
+ words = %w{the quick brown fox jumped over the lazy dog}.cycle
20
+
21
+ dir = Dir.mktmpdir
22
+
23
+ word_tests = [1] +(5..50).step(5).to_a
24
+
25
+ html = File.join(dir, 'sample.html')
26
+ open(html, 'w') do |f|
27
+ source_images.each do |ext, data|
28
+ word_tests.each do |num_words|
29
+ img_file = File.join(dir, "i#{num_words}.#{ext}")
30
+ puts img_file
31
+ MemeCaptain.meme_top_bottom(data, words.take(num_words).join(' '), nil, font: 'Impact-Regular').write(img_file)
32
+ f.write("<img src=\"#{img_file}\">\n")
33
+ end
34
+ end
35
+ end
36
+
37
+ `open #{html}`
38
+ end
@@ -4,11 +4,5 @@ require 'meme_captain/draw'
4
4
  require 'meme_captain/image_list'
5
5
  require 'meme_captain/meme'
6
6
  require 'meme_captain/memebg'
7
- require 'meme_captain/meme_data'
8
- require 'meme_captain/norm_params'
9
- require 'meme_captain/pretty_format'
10
- require 'meme_captain/server'
11
- require 'meme_captain/source_fetch_fail'
12
7
  require 'meme_captain/text_pos'
13
- require 'meme_captain/upload'
14
8
  require 'meme_captain/version'
@@ -1,14 +1,19 @@
1
+ # encoding: UTF-8
2
+
1
3
  module MemeCaptain
2
4
 
3
5
  class Caption < String
4
6
 
5
- def initialize(s='')
7
+ def initialize(s = '')
6
8
  super s.to_s
7
9
  end
8
10
 
9
11
  # Return the contents of the string quoted for ImageMagick annotate.
10
12
  def annotate_quote
11
- Caption.new(gsub('\\', '\\\\\\').gsub('%', '\%'))
13
+ Caption.new(
14
+ gsub('\\', '\\\\\\').
15
+ gsub('%', '%%').
16
+ gsub(/^@/, '\@'))
12
17
  end
13
18
 
14
19
  # Whether the string contains any non-whitespace.
@@ -27,9 +32,9 @@ module MemeCaptain
27
32
  if lines.empty?
28
33
  lines << word
29
34
  else
30
- if (lines[-1].size + 1 + word.size) <= chars_per_line or
31
- lines.size >= num_lines
32
- lines[-1] << ' ' unless lines[-1].empty?
35
+ if (lines[-1].size + 1 + word.size) <= chars_per_line ||
36
+ lines.size >= num_lines
37
+ lines[-1] << ' ' unless lines[-1].empty?
33
38
  lines[-1] << word
34
39
  else
35
40
  lines << word
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module MemeCaptain
2
4
 
3
5
  # For comparing different caption line break and pointsize choices.
@@ -17,7 +19,7 @@ module MemeCaptain
17
19
  end
18
20
 
19
21
  def fits
20
- metrics.width <= bound_width and metrics.height <= bound_height
22
+ metrics.width <= bound_width && metrics.height <= bound_height
21
23
  end
22
24
 
23
25
  def fits_i
@@ -1,6 +1 @@
1
- require 'meme_captain/image_list/cache'
2
- require 'meme_captain/image_list/fetch'
3
- require 'meme_captain/image_list/fetch_error'
4
1
  require 'meme_captain/image_list/watermark'
5
-
6
- require 'meme_captain/image_list/source_image'
@@ -1,4 +1,4 @@
1
- require 'RMagick'
1
+ require 'rmagick'
2
2
 
3
3
  module MemeCaptain
4
4
 
@@ -1,4 +1,4 @@
1
- require 'RMagick'
1
+ require 'rmagick'
2
2
 
3
3
  module MemeCaptain
4
4
 
@@ -21,7 +21,7 @@ module MemeCaptain
21
21
 
22
22
  img.auto_orient!
23
23
 
24
- super_sample = options[:super_sample] || 2.0
24
+ super_sample = options[:super_sample] || 1.0
25
25
 
26
26
  text_layer = Magick::Image.new(
27
27
  img.page.width * super_sample, img.page.height * super_sample) {
@@ -77,6 +77,10 @@ module MemeCaptain
77
77
  draw.annotate text_layer, text_width, text_height, text_x, text_y,
78
78
  choice.text
79
79
 
80
+ text_layer.virtual_pixel_method = Magick::TransparentVirtualPixelMethod
81
+ text_layer = text_layer.blur_channel(text_pos.draw_options[:stroke_width] / 2.0,
82
+ text_pos.draw_options[:stroke_width] / 4.0, Magick::OpacityChannel)
83
+
80
84
  draw.stroke = 'none'
81
85
 
82
86
  draw.annotate text_layer, text_width, text_height, text_x, text_y,
@@ -1,4 +1,4 @@
1
- require 'RMagick'
1
+ require 'rmagick'
2
2
 
3
3
  module MemeCaptain
4
4
 
@@ -1,4 +1,6 @@
1
- require 'RMagick'
1
+ # encoding: UTF-8
2
+
3
+ require 'rmagick'
2
4
 
3
5
  module MemeCaptain
4
6
 
@@ -13,7 +15,7 @@ module MemeCaptain
13
15
  #
14
16
  # x, y, width and height can be in pixels or a float that represents a
15
17
  # percentage of the width and height of the image the text is put onto.
16
- def initialize(text, x, y, width, height, options={})
18
+ def initialize(text, x, y, width, height, options = {})
17
19
  @text = text
18
20
  @x = x
19
21
  @y = y
@@ -24,11 +26,11 @@ module MemeCaptain
24
26
  @min_pointsize = options.delete(:min_pointsize) || 12
25
27
 
26
28
  @draw_options = {
27
- :fill => 'white',
28
- :font => 'Impact',
29
- :gravity => Magick::CenterGravity,
30
- :stroke => 'black',
31
- :stroke_width => 8,
29
+ fill: 'white',
30
+ font: 'Impact',
31
+ gravity: Magick::CenterGravity,
32
+ stroke: 'black',
33
+ stroke_width: 8,
32
34
  }.merge(options)
33
35
  end
34
36
 
@@ -1,3 +1,3 @@
1
1
  module MemeCaptain
2
- VERSION = '0.1.2'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -12,25 +12,14 @@ Gem::Specification.new do |s|
12
12
  s.homepage = 'https://github.com/mmb/meme_captain'
13
13
  s.authors = ['Matthew M. Boedicker']
14
14
  s.email = %w{matthewm@boedicker.org}
15
+ s.license = 'MIT'
15
16
 
16
- %w{
17
- bson_ext
18
- curb
19
- json
20
- mime-types
21
- mongo
22
- mongo_mapper
23
- rack
24
- rack-contrib
25
- rack-rewrite
26
- rmagick
27
- sinatra
28
- }.each { |g| s.add_dependency g }
17
+ s.add_dependency 'mime-types', '~> 3.3.1'
18
+ s.add_dependency 'rmagick', '~> 4.1.2'
29
19
 
30
- %w{
31
- rspec
32
- webmock
33
- }.each { |g| s.add_development_dependency g }
20
+ s.add_development_dependency 'rake', '~> 13.0.1'
21
+ s.add_development_dependency 'rspec', '~> 3.9.0'
22
+ s.add_development_dependency 'webmock', '~> 3.8.3'
34
23
 
35
24
  s.files = `git ls-files`.split("\n")
36
25
  s.executables = %w{memecaptain}
Binary file
Binary file
@@ -11,7 +11,7 @@ describe MemeCaptain::CaptionChoice do
11
11
  caption_choice2 = MemeCaptain::CaptionChoice.new(12, metrics,
12
12
  "the quick brown fox", 200, 100)
13
13
 
14
- caption_choice1.should be < caption_choice2
14
+ expect(caption_choice1 < caption_choice2).to be(true)
15
15
  end
16
16
 
17
17
  it 'should rank choices with higher point size higher' do
@@ -23,7 +23,7 @@ describe MemeCaptain::CaptionChoice do
23
23
  caption_choice2 = MemeCaptain::CaptionChoice.new(13, metrics,
24
24
  "the quick brown fox", 200, 100)
25
25
 
26
- caption_choice1.should be < caption_choice2
26
+ expect(caption_choice1 < caption_choice2).to be(true)
27
27
  end
28
28
 
29
29
  it 'should rank choices with less lines higher when the text fits' do
@@ -35,7 +35,7 @@ describe MemeCaptain::CaptionChoice do
35
35
  caption_choice2 = MemeCaptain::CaptionChoice.new(12, metrics,
36
36
  "the quick brown fox", 200, 100)
37
37
 
38
- caption_choice1.should be < caption_choice2
38
+ expect(caption_choice1 < caption_choice2).to be(true)
39
39
  end
40
40
 
41
41
  it 'should rank choices with more lines higher when the text does not fit' do
@@ -47,7 +47,7 @@ describe MemeCaptain::CaptionChoice do
47
47
  caption_choice2 = MemeCaptain::CaptionChoice.new(12, metrics,
48
48
  "the quick\nbrown fox", 200, 99)
49
49
 
50
- caption_choice1.should be < caption_choice2
50
+ expect(caption_choice1 < caption_choice2).to be(true)
51
51
  end
52
52
 
53
53
  end
@@ -3,43 +3,52 @@ require 'meme_captain'
3
3
  describe MemeCaptain::Caption do
4
4
 
5
5
  it 'should quote backslashes for ImageMagick annotate' do
6
- MemeCaptain::Caption.new('\\foo\\bar\\').annotate_quote.should ==
7
- '\\\\foo\\\\bar\\\\'
6
+ expect(MemeCaptain::Caption.new('\\foo\\bar\\').annotate_quote).to eq(
7
+ '\\\\foo\\\\bar\\\\')
8
8
  end
9
9
 
10
10
  it 'should quote percent signs for ImageMagick annotate' do
11
- MemeCaptain::Caption.new('%foo%bar%').annotate_quote.should ==
12
- '\%foo\%bar\%'
11
+ expect(MemeCaptain::Caption.new('%foo%bar%').annotate_quote).to eq(
12
+ '%%foo%%bar%%')
13
+ end
14
+
15
+ it 'should quote attribute percent escapes' do
16
+ expect(MemeCaptain::Caption.new('%m %m %b %#').annotate_quote).to eq(
17
+ '%%m %%m %%b %%#')
18
+ end
19
+
20
+ it 'should quote an @ symbol if it is the first character' do
21
+ expect(MemeCaptain::Caption.new('@hi').annotate_quote).to eq('\@hi')
13
22
  end
14
23
 
15
24
  it 'should be drawable if it contains at least one non-whitespace character' do
16
- MemeCaptain::Caption.new('a').should be_drawable
25
+ expect(MemeCaptain::Caption.new('a').drawable?).to be(true)
17
26
  end
18
27
 
19
28
  it 'should not be drawable if it is all whitespace' do
20
- MemeCaptain::Caption.new(' ').should_not be_drawable
29
+ expect(MemeCaptain::Caption.new(' ').drawable?).to be(false)
21
30
  end
22
31
 
23
32
  it 'should not be drawable if it is empty' do
24
- MemeCaptain::Caption.new('').should_not be_drawable
33
+ expect(MemeCaptain::Caption.new('').drawable?).to be(false)
25
34
  end
26
35
 
27
36
  it 'should not be drawable if it is nil' do
28
- MemeCaptain::Caption.new(nil).should_not be_drawable
37
+ expect(MemeCaptain::Caption.new(nil).drawable?).to be(false)
29
38
  end
30
39
 
31
40
  it 'should wrap a string into two roughly equal lines' do
32
- MemeCaptain::Caption.new(
33
- 'the quick brown fox jumped over the lazy dog').wrap(2).should ==
34
- "the quick brown fox\njumped over the lazy dog"
41
+ expect(MemeCaptain::Caption.new(
42
+ 'the quick brown fox jumped over the lazy dog').wrap(2)).to eq(
43
+ "the quick brown fox\njumped over the lazy dog")
35
44
  end
36
45
 
37
46
  it 'should wrap a string into as many lines as it can' do
38
- MemeCaptain::Caption.new('foo bar').wrap(3).should == "foo\nbar"
47
+ expect(MemeCaptain::Caption.new('foo bar').wrap(3)).to eq("foo\nbar")
39
48
  end
40
49
 
41
50
  it 'should not wrap text with no whitespace' do
42
- MemeCaptain::Caption.new('foobar').wrap(2).should == 'foobar'
51
+ expect(MemeCaptain::Caption.new('foobar').wrap(2)).to eq('foobar')
43
52
  end
44
53
 
45
54
  end
@@ -12,8 +12,22 @@ describe MemeCaptain, '.meme_top_bottom' do
12
12
  :body => Base64.decode64(
13
13
  'iVBORw0KGgoAAAANSUhEUgAAAcwAAAAyAgMAAACsWgPIAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wBHwQoJY1iyrwAAAAJUExURQAAAAAAAP///4Pdz9IAAAABdFJOUwBA5thmAAAAAWJLR0QB/wIt3gAAAHpJREFUWIXt1zESgCAMRNE03s9mG+9ns6e0EaKCqDOWf4sUJOHREvqciOn7Us0cEZiYmJhnc7HtVbJtS5LsVRo09DScZzmSG5iYmJit2RTVlduGquS920hFvxRMTEzMRzOv6TfKheMX9ThMTEzMnvlj5ld/S0xMTMxjNoGjc3pdi6L4AAAAAElFTkSuQmCC'))
14
14
 
15
+ font = File.expand_path('../assets/Coda-Heavy.ttf', __FILE__)
15
16
  i = MemeCaptain.meme_top_bottom(
16
- open('http://memecaptain.com/good.jpg'), 'top text', 'bottom text')
17
+ open('http://memecaptain.com/good.jpg'), 'top text', 'bottom text',
18
+ font: font)
17
19
  end
18
20
 
21
+ context 'when one of the captions starts with an @ symbol' do
22
+ it 'generates the image' do
23
+ font = File.expand_path('../assets/Coda-Heavy.ttf', __FILE__)
24
+ src_image = File.expand_path('../assets/town_crier.jpg', __FILE__)
25
+
26
+ expect do
27
+ File.open(src_image) do |f|
28
+ MemeCaptain.meme_top_bottom(f, '@foo', '@bar', font: font)
29
+ end
30
+ end.to_not raise_exception
31
+ end
32
+ end
19
33
  end