emojimage 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 490ba084f2ea9c0edcbfa44ef893633f1f847320
4
+ data.tar.gz: 8dac8a5a3d8c0d7445bca8a397886ed4203b11de
5
+ SHA512:
6
+ metadata.gz: 79c1e7bdda86609c26acaef8ed06b1bfadac9cbaf2b2887bb350edb94be64126da36b2cfcd0ad69626c3ba966e629aa43277597eaa8791b02292481f8ca003f0
7
+ data.tar.gz: d8da10d81e0d812309b03db17b7b6c49863fd7b286afc4f7c410a4494c48a79785d58cacb52744a2bfe85aeece86069b52c9fc752ea9a3f9b64a0a0d4c0b2a08
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ public/data/*.json
11
+ public/images
12
+ .DS_Store
13
+ java/
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in emojimage.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 James Anthony Bruno
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # Emojimage
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/emojimage`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'emojimage'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install emojimage
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec emojimage` to use the gem in this directory, ignoring other installed copies of this gem.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/emojimage.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require "gemoji"
3
+
4
+ load 'tasks/emoji.rake'
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "emojimage"
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
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'emojimage/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "emojimage"
8
+ spec.version = Emojimage::VERSION
9
+ spec.authors = ["James Anthony Bruno"]
10
+ spec.email = ["j.bruno.che@gmail.com"]
11
+
12
+ spec.summary = "Turn images into collages of emoji"
13
+ spec.description = "Turn images into collages of emoji"
14
+ spec.homepage = "https://github.com/EVA-01/emojimage"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.10"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+
25
+ spec.add_runtime_dependency "gemoji", "~> 2.1.0"
26
+ spec.add_runtime_dependency "json", "~> 1.8.3"
27
+ spec.add_runtime_dependency "oily_png", "~> 1.2.0"
28
+ spec.add_runtime_dependency "thor", "~> 0.19.1"
29
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "emojimage"
4
+
5
+ Emojimage::CLI.start(ARGV)
@@ -0,0 +1,4 @@
1
+ require "emojimage/version"
2
+ require "emojimage/emojimage"
3
+ require "emojimage/converted"
4
+ require "emojimage/cli"
@@ -0,0 +1,32 @@
1
+ require 'thor'
2
+
3
+ module Emojimage
4
+ class CLI < Thor
5
+ option :size, :default => 4, :aliases => "-s", :type => :numeric
6
+ option :transparency, :default => true, :aliases => "-T", :type => :boolean
7
+ option :blend, :default => [255, 255, 255], :aliases => "-b", :type => :array
8
+ option :output, :required => true, :aliases => "-o", :type => :string
9
+ option :wrap, :default => true, :aliases => "-w", :type => :boolean
10
+ option :type, :required => true, :aliases => "-t", :type => :string, :enum => ["text", "html", "image"]
11
+ desc "cast INPUT [options]", "Convert image to emoji"
12
+ ##
13
+ # CLI option to convert and save image.
14
+ def cast(image)
15
+ c = []
16
+ for comp in options['blend']
17
+ c << comp.to_i
18
+ end
19
+ if c.length == 1
20
+ color = ChunkyPNG::Color.rgb(c[0], c[0], c[0])
21
+ elsif c.length == 3
22
+ color = ChunkyPNG::Color.rgb(c[0], c[1], c[2])
23
+ else
24
+ raise "Bad RGB in blend option"
25
+ end
26
+ spell = Emojimage::Converted.new image, options['size']
27
+ spell.run options['transparency'], color
28
+ spell.save options['output'], options['type'].to_sym, options['wrap']
29
+ end
30
+ default_task :cast
31
+ end
32
+ end
@@ -0,0 +1,117 @@
1
+ module Emojimage
2
+ ##
3
+ # The canvas
4
+ class Converted
5
+ attr_reader :image, :size, :emoji
6
+ ##
7
+ # `img` is the input image. Should be either a file path or a `ChunkyPNG::Image`. `size` is the chunk size that will be converted to emoji.
8
+ def initialize img, size = 4
9
+ if img.class == String
10
+ img = ChunkyPNG::Image.from_file img
11
+ elsif img.class != ChunkyPNG::Image
12
+ raise "Unknown image representation"
13
+ end
14
+ if size < 1
15
+ raise "Use a size more than 0"
16
+ end
17
+ @size = size
18
+ @emoji = []
19
+ @image = nil
20
+ @original = img
21
+ end
22
+ ##
23
+ # Run the conversion. If `transparentBlock` is true, the image will retain transparency. If false, wholly transparent areas will be emoji. Blends the transparent/semi-transparent with `blend` color.
24
+ def run transparentBlock = false, blend = ChunkyPNG::Color::WHITE
25
+ img = @original
26
+ w = img.width
27
+ h = img.height
28
+ @image = ChunkyPNG::Image.new(w, h)
29
+ (0...h).step(size).each do |row|
30
+ rowmoji = []
31
+ (0...w).step(size).each do |column|
32
+ pxls = []
33
+ for y in (0...size)
34
+ if img.include_y?(y + row)
35
+ for x in (0...size)
36
+ pxls << img[x + column, y + row] if img.include_x?(x + column)
37
+ end
38
+ end
39
+ end
40
+ value = Emojimage.average pxls, transparentBlock, blend
41
+ if value == ChunkyPNG::Color::TRANSPARENT
42
+ rowmoji << " "
43
+ else
44
+ found = Emojimage.find value, blend
45
+ rowmoji << found
46
+ emoji = Emojimage.chunkemoji(found).resample_nearest_neighbor size, size
47
+ for y in 0...size
48
+ if img.include_y?(y + row)
49
+ for x in 0...size
50
+ if img.include_x?(x + column)
51
+ @image[x + column, y + row] = emoji[x, y]
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ @emoji << rowmoji
59
+ end
60
+ end
61
+ ##
62
+ # Outputs the emoji as raw text. **Run `run` first.**
63
+ def text
64
+ raise "Use 'run' first" if @image == nil
65
+ rows = []
66
+ for row in @emoji
67
+ txt = ""
68
+ for col in row
69
+ if col == " "
70
+ txt += " "
71
+ else
72
+ txt += col['unicode']
73
+ end
74
+ end
75
+ rows << txt
76
+ end
77
+ rows.join "\n"
78
+ end
79
+ ##
80
+ # Outputs the emoji as HTML. If `wrap` is false, the emoji will not be placed in a code-block.
81
+ def html wrap = true
82
+ raise "Use 'run' first" if @image == nil
83
+ rows = []
84
+ for row in @emoji
85
+ txt = ""
86
+ for col in row
87
+ if col == " "
88
+ txt += "&nbsp;"
89
+ else
90
+ for h in col['key']
91
+ txt += "&\##{h.to_i(16)};"
92
+ end
93
+ end
94
+ end
95
+ rows << txt
96
+ end
97
+ if wrap
98
+ "<code><pre style='font-family: \"Apple Color Emoji\"; font-size: #{@size}px; line-height:1em'>#{rows.join "\n"}</pre></code>"
99
+ else
100
+ rows.join "\n"
101
+ end
102
+ end
103
+ ##
104
+ # Save to `fn`. `what` is one of `:image`, `:text`, `:html`. `wrap` affects `:html` output.
105
+ def save fn, what = :image, wrap = true
106
+ raise "Use 'run' first" if @image == nil
107
+ case what
108
+ when :image
109
+ @image.save fn
110
+ when :text
111
+ File.open(fn, "w+") { |f| f.write text }
112
+ when :html
113
+ File.open(fn, "w+") { |f| f.write html(wrap) }
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,129 @@
1
+ require "gemoji"
2
+ require "json"
3
+ require "oily_png"
4
+
5
+ module Emojimage
6
+ extend self
7
+
8
+ @@emoji = Emoji.all.select { |char| !char.custom? }
9
+ @@where = File.expand_path "../", File.dirname(__FILE__)
10
+ @@info = false
11
+ ##
12
+ # All the emoji
13
+ def emoji
14
+ @@emoji
15
+ end
16
+ ##
17
+ # Grab emoji image
18
+ def where e
19
+ if e.class == Hash
20
+ address = e['filename']
21
+ elsif e.class == Emoji::Character
22
+ address = e.image_filename
23
+ else
24
+ raise "Unknown emoji representation passed to Emojimage.where"
25
+ end
26
+ within "../public/images/emoji/#{address}"
27
+ end
28
+ ##
29
+ # Find relative path.
30
+ def within path
31
+ File.expand_path path, @@where
32
+ end
33
+ ##
34
+ # Average of an array of colors. Returns `ChunkyPNG::Color::TRANSPARENT` if `transparentBlock` is true and the colors are all transparent. Blends the transparent/semi-transparent with `blend` color.
35
+ def average colors, transparentBlock = false, blend = ChunkyPNG::Color::WHITE
36
+ color = [0.0,0.0,0.0,0.0]
37
+ count = 0.0
38
+ for pxl in colors
39
+ weight = ((255 - (ChunkyPNG::Color.a pxl)) / 255.0).to_f
40
+ color[0] += ((1.0 - weight) * (ChunkyPNG::Color.r pxl).to_f + weight * (ChunkyPNG::Color.r blend).to_f)
41
+ color[1] += ((1.0 - weight) * (ChunkyPNG::Color.g pxl).to_f + weight * (ChunkyPNG::Color.g blend).to_f)
42
+ color[2] += ((1.0 - weight) * (ChunkyPNG::Color.b pxl).to_f + weight * (ChunkyPNG::Color.b blend).to_f)
43
+ color[3] += ChunkyPNG::Color.a pxl
44
+ count += 1.0
45
+ end
46
+ if transparentBlock and color[3] == 0.0
47
+ ChunkyPNG::Color::TRANSPARENT
48
+ else
49
+ ChunkyPNG::Color.rgb (color[0]/count).round, (color[1]/count).round, (color[2]/count).round
50
+ end
51
+ end
52
+ ##
53
+ # Get the overall average color of an image.
54
+ def analyze img
55
+ average img.pixels
56
+ end
57
+ ##
58
+ # Has this been set up with the current `blend` setting?
59
+ def setup? blend
60
+ gemojiV = "#{Gem.loaded_specs['gemoji'].version.to_s}\n#{blend}"
61
+ lastImport = File.open(within("../public/data/.last"), 'rb') { |f| f.read }
62
+ lastImport == gemojiV
63
+ end
64
+ ##
65
+ # Sets up the enviroments by grabbing the emoji images and setting emoji info.
66
+ def setup blend
67
+ gemojiV = "#{Gem.loaded_specs['gemoji'].version.to_s}\n#{blend}"
68
+ unless setup? blend
69
+ system("cd #{within "../"} && rake emoji")
70
+ # puts "Initialized emoji images"
71
+ codify blend
72
+ File.open(within("../public/data/.last"), "w+") { |f| f.write gemojiV }
73
+ # puts "Analyzed emoji images"
74
+ end
75
+ end
76
+ ##
77
+ # Grab emoji info. If it doesn't exist, return `false`.
78
+ def emojinfo
79
+ if @@info == false
80
+ if File.exist?(within("../public/data/emoji.json"))
81
+ @@info = JSON.parse(File.open(within("../public/data/emoji.json"), 'rb') { |f| f.read })
82
+ else
83
+ @@info = false
84
+ end
85
+ end
86
+ @@info
87
+ end
88
+ ##
89
+ # Splits a hex value in case there are two hexes inside
90
+ def unpackhex c
91
+ c.hex_inspect.split '-'
92
+ end
93
+ ##
94
+ # Create JSON file with info about emoji.
95
+ def codify blend = ChunkyPNG::Color::WHITE
96
+ res = {"characters" => []}
97
+ for e in @@emoji
98
+ png = chunkemoji e
99
+ res["characters"] << {
100
+ "filename" => e.image_filename,
101
+ "value" => average(png.pixels, false, blend),
102
+ "unicode" => e.unicode_aliases.first,
103
+ "key" => unpackhex(e)
104
+ }
105
+ end
106
+ File.open(within("../public/data/emoji.json"), "w+") { |f| f.write res.to_json }
107
+ end
108
+ ##
109
+ # Get distance between two colors.
110
+ def compare c1, c2
111
+ Math.sqrt((ChunkyPNG::Color.r(c1)-ChunkyPNG::Color.r(c2))**2+(ChunkyPNG::Color.g(c1)-ChunkyPNG::Color.g(c2))**2+(ChunkyPNG::Color.b(c1)-ChunkyPNG::Color.b(c2))**2)
112
+ end
113
+ ##
114
+ # Get emoji that corresponds to `color`. `blend` represents a color to blend with for transparency (in other words, a background color).
115
+ def find color, blend
116
+ setup blend
117
+ data = emojinfo
118
+ if color == ChunkyPNG::Color::TRANSPARENT
119
+ false
120
+ else
121
+ data["characters"].min_by { |char| compare color, char["value"] }
122
+ end
123
+ end
124
+ ##
125
+ # Get `ChunkyPNG::Image` from emoji
126
+ def chunkemoji e
127
+ ChunkyPNG::Image.from_file(where e)
128
+ end
129
+ end
@@ -0,0 +1,3 @@
1
+ module Emojimage
2
+ VERSION = "0.1.0"
3
+ end
File without changes
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: emojimage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Anthony Bruno
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-06 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.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
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: gemoji
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.8.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: oily_png
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.19.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.19.1
97
+ description: Turn images into collages of emoji
98
+ email:
99
+ - j.bruno.che@gmail.com
100
+ executables:
101
+ - emojimage
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - emojimage.gemspec
114
+ - exe/emojimage
115
+ - lib/emojimage.rb
116
+ - lib/emojimage/cli.rb
117
+ - lib/emojimage/converted.rb
118
+ - lib/emojimage/emojimage.rb
119
+ - lib/emojimage/version.rb
120
+ - public/data/.last
121
+ homepage: https://github.com/EVA-01/emojimage
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.4.5.1
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Turn images into collages of emoji
145
+ test_files: []