camalian 0.0.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cbf6f55fe49509d8e0ae73b3ee3717026bea081f
4
- data.tar.gz: 810535ed27dcd19b903aedbe3b2825baf7ce4ea3
2
+ SHA256:
3
+ metadata.gz: bdc6f4d61421eac9f0017baf9e6f290c37e47b633ee4533e18d00883fd162b54
4
+ data.tar.gz: 5cb477be826b4c0706a9385ce31699a34aab8b27c66c5c57140d1818650ca60e
5
5
  SHA512:
6
- metadata.gz: cbbf8aca2ebe72c607b6dc1a38fb2ca5adb36a15590088e30643c25ba67e7fd8c3a0eee0b1907c03a9e13342c258f5642ab3fe7b2e94c08ea8eb841e92d944e8
7
- data.tar.gz: 8c13c34b6c99cd644eed763d1e36d90304a3116b96adcb1edd26e85da5884aec596e6ffc9ab67dafc382113900286dd0714ec7b8cec94558e3bc08fa66f3f687
6
+ metadata.gz: 912bcad8d3db3362d2997877fe42b9d2df01c806b9bbfe965463d5df8e530dab55f716820f414e44910e5818ff86ac1ac256f8c9d1a2d760ca75d38c69492dcc
7
+ data.tar.gz: fe6989ee96c21f12482857c26aed89f7db69e6d1a41616c9aaed3a11732ccf76c8376c6711b49dc375cbb8d29adfef1ff09ba3ea3c5780c4f70cdce0431041eb
@@ -0,0 +1,30 @@
1
+ name: Github Packages Push
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - '*'
8
+ jobs:
9
+ build:
10
+ name: Build + Publish
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby 2.6
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.6.x
19
+
20
+ - name: Publish to GPR
21
+ run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
26
+ gem build *.gemspec
27
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
28
+ env:
29
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
30
+ OWNER: ${{ github.repository_owner }}
@@ -0,0 +1,32 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: build
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-16.04
19
+ strategy:
20
+ matrix:
21
+ ruby: [ '2.4', '2.5', '2.6', '2.7' ]
22
+ name: Ruby ${{ matrix.ruby }}
23
+ steps:
24
+ - uses: actions/checkout@v2
25
+ - uses: actions/setup-ruby@v1
26
+ with:
27
+ ruby-version: ${{ matrix.ruby }}
28
+ - name: Install dependencies
29
+ run: bundle install
30
+ - name: Run tests
31
+ run: bundle exec rake
32
+
@@ -0,0 +1,29 @@
1
+ name: Ruby Gems Push
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - '*'
8
+ jobs:
9
+ build:
10
+ name: Build + Publish
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby 2.6
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.6.x
19
+
20
+ - name: Publish to RubyGems
21
+ run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
26
+ gem build *.gemspec
27
+ gem push *.gem
28
+ env:
29
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .idea/
18
+ .idea/
19
+ coverage/
@@ -0,0 +1,33 @@
1
+ # Use this file to configure the Overcommit hooks you wish to use. This will
2
+ # extend the default configuration defined in:
3
+ # https://github.com/sds/overcommit/blob/master/config/default.yml
4
+ #
5
+ # At the topmost level of this YAML file is a key representing type of hook
6
+ # being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
7
+ # customize each hook, such as whether to only run it on certain files (via
8
+ # `include`), whether to only display output if it fails (via `quiet`), etc.
9
+ #
10
+ # For a complete list of hooks, see:
11
+ # https://github.com/sds/overcommit/tree/master/lib/overcommit/hook
12
+ #
13
+ # For a complete list of options that you can use to customize hooks, see:
14
+ # https://github.com/sds/overcommit#configuration
15
+ #
16
+ # Uncomment the following lines to make the configuration take effect.
17
+
18
+ PreCommit:
19
+ RuboCop:
20
+ enabled: true
21
+ on_warn: fail # Treat all warnings as failures
22
+
23
+ # TrailingWhitespace:
24
+ # enabled: true
25
+ # exclude:
26
+ # - '**/db/structure.sql' # Ignore trailing whitespace in generated files
27
+ #
28
+ #PostCheckout:
29
+ # ALL: # Special hook name that customizes all hooks of this type
30
+ # quiet: true # Change all post-checkout hooks to only display output on failure
31
+ #
32
+ # IndexTags:
33
+ # enabled: true # Generate a tags file with `ctags` each time HEAD changes
@@ -0,0 +1,33 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+
12
+ AllCops:
13
+ NewCops: enable
14
+
15
+ Naming/MethodParameterName:
16
+ AllowedNames:
17
+ - r
18
+ - g
19
+ - b
20
+
21
+ Metrics/MethodLength:
22
+ Max: 50
23
+
24
+ Metrics/PerceivedComplexity:
25
+ Max: 25
26
+
27
+ Metrics/CyclomaticComplexity:
28
+ Max: 15
29
+
30
+ Metrics/AbcSize:
31
+ Max: 20
32
+ IgnoredMethods:
33
+ - build_components
@@ -0,0 +1 @@
1
+ ruby 2.7.1
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.7
4
+ - 2.6
5
+ - 2.5
6
+ - 2.4
7
+
8
+ before_script:
9
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
10
+ - chmod +x ./cc-test-reporter
11
+ - ./cc-test-reporter before-build
12
+
13
+ script:
14
+ - bundle exec rake test
15
+
16
+ after_script:
17
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in camalian.gemspec
4
6
  gemspec
7
+
8
+ gem 'rubocop', '~> 1.3', require: false
9
+ gem 'simplecov', require: false
data/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # Camalian
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/camalian.svg)](https://badge.fury.io/rb/camalian)
4
+ ![Ruby](https://github.com/nazarhussain/camalian/workflows/build/badge.svg?branch=master)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/5495a2c122469d81b6c5/maintainability)](https://codeclimate.com/github/nazarhussain/camalian/maintainability)
6
+
3
7
  Ruby gem to extract color palettes from images and play with their saturation
4
8
 
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
8
12
 
9
- gem 'camalian', '~> 0.0.3'
13
+ gem 'camalian', '~> 0.1.0'
10
14
 
11
15
  And then execute:
12
16
 
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
 
3
5
  require 'rake/testtask'
4
6
 
@@ -6,5 +8,5 @@ Rake::TestTask.new do |t|
6
8
  t.libs << 'test'
7
9
  end
8
10
 
9
- desc "Run tests"
10
- task :default => :test
11
+ desc 'Run tests'
12
+ task default: :test
@@ -1,27 +1,28 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'camalian/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "camalian"
8
+ spec.name = 'camalian'
8
9
  spec.version = Camalian::VERSION
9
- spec.authors = ["Nazar Hussain"]
10
- spec.email = ["nazarhussain@gmail.com"]
11
- spec.description = %q{Library used to deal with colors and images}
12
- spec.summary = %q{Library used to deal with colors and images. You can extract colors from images.}
13
- spec.homepage = "https://github.com/nazarhussain/camalian"
14
- spec.license = "MIT"
10
+ spec.authors = ['Nazar Hussain']
11
+ spec.email = ['nazarhussain@gmail.com']
12
+ spec.description = 'Library used to deal with colors and images'
13
+ spec.summary = 'Library used to deal with colors and images. You can extract colors from images.'
14
+ spec.homepage = 'https://github.com/nazarhussain/camalian'
15
+ spec.license = 'MIT'
15
16
 
16
- spec.files = `git ls-files`.split($/)
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
+ spec.require_paths = ['lib']
20
21
 
21
- spec.requirements = 'ImageMagick'
22
+ spec.add_dependency 'chunky_png', '~> 1.3', '>= 1.3.14'
22
23
 
23
- spec.add_dependency "cocaine"
24
- spec.add_dependency "rmagick", "~> 2.15.4"
25
- spec.add_dependency "oily_png", "~> 1.2.0"
24
+ spec.add_development_dependency 'minitest', '~> 5.14', '>= 5.14.2'
25
+ spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
26
26
 
27
+ spec.required_ruby_version = '>= 2.4'
27
28
  end
@@ -1,25 +1,27 @@
1
- require "oily_png"
2
- require "tempfile"
3
- require "open-uri"
4
- require "cocaine"
5
- require "chunky_png_patch/color"
1
+ # frozen_string_literal: true
6
2
 
7
- require "camalian/version"
8
- require "camalian/color"
9
- require "camalian/palette"
10
- require "camalian/image"
3
+ require 'chunky_png'
4
+ require 'tempfile'
5
+ require 'open-uri'
6
+
7
+ require 'camalian/version'
8
+ require 'camalian/color'
9
+ require 'camalian/palette'
10
+ require 'camalian/image'
11
+ require 'camalian/quantization/histogram'
12
+
13
+ module Camalian # :nodoc:
14
+ QUANTIZATION_HISTOGRAM = 'histogram'
11
15
 
12
- module Camalian
13
16
  class << self
14
17
  def options
15
- convert = `which convert`.strip
16
18
  @options ||= {
17
- :image_magick_path => convert.length > 0 ? convert : '/usr/bin/convert',
18
- :color_count => 8,
19
+ color_count: 8,
20
+ quantization: Camalian::QUANTIZATION_HISTOGRAM
19
21
  }
20
22
  end
21
23
 
22
- def load(image_path)
24
+ def load(image_path)
23
25
  Image.new(image_path)
24
26
  end
25
27
  end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Camalian
4
+ # Camalian color object
2
5
  class Color
3
-
4
6
  attr_reader :r, :g, :b, :h, :s, :l, :hsv
5
7
 
6
- def initialize(*value)
7
- if value.size == 1
8
- rgb = extract_rgb(value.first)
9
- build_components(rgb[0], rgb[1], rgb[2])
10
- elsif value.size == 3
11
- build_components(value[0], value[1], value[2])
12
- end
8
+ def initialize(r, g, b)
9
+ build_components(r, g, b)
10
+ end
11
+
12
+ def self.from_hex(hex_value)
13
+ r, g, b = extract_rgb(hex_value)
14
+ Color.new(r, g, b)
13
15
  end
14
16
 
15
17
  def to_s
@@ -21,7 +23,7 @@ module Camalian
21
23
  end
22
24
 
23
25
  def distance(color)
24
- [(self.h - color.h) % 360, (color.h - self.h) % 360].min
26
+ [(h - color.h) % 360, (color.h - h) % 360].min
25
27
  end
26
28
 
27
29
  def extract_rgb(color_hash)
@@ -35,7 +37,7 @@ module Camalian
35
37
 
36
38
  private
37
39
 
38
- def build_components(r,g,b)
40
+ def build_components(r, g, b)
39
41
  @r = r
40
42
  @g = g
41
43
  @b = b
@@ -50,21 +52,21 @@ module Camalian
50
52
 
51
53
  @l = (cmax + cmin) / 2.0
52
54
 
53
- if delta == 0
55
+ if delta.zero?
54
56
  @h = 0
55
57
  elsif cmax == ri
56
58
  @h = 60 * (((gi - bi) / delta) % 6)
57
59
  elsif cmax == gi
58
- @h = 60 * (((bi - ri)/ delta) + 2)
60
+ @h = 60 * (((bi - ri) / delta) + 2)
59
61
  elsif cmax == bi
60
- @h = 60 * (((ri - gi)/ delta) + 4)
62
+ @h = 60 * (((ri - gi) / delta) + 4)
61
63
  end
62
64
 
63
- if (delta == 0)
64
- @s = 0
65
- else
66
- @s = delta / ( 1 - (2*@l -1).abs )
67
- end
65
+ @s = if delta.zero?
66
+ 0
67
+ else
68
+ delta / (1 - (2 * @l - 1).abs)
69
+ end
68
70
 
69
71
  @h = @h.round(2)
70
72
  @s = (@s * 100).round(2)
@@ -72,22 +74,22 @@ module Camalian
72
74
 
73
75
  # HSV Calculation
74
76
  # Hue calculation
75
- if delta == 0
77
+ if delta.zero?
76
78
  @hsv = [0]
77
79
  elsif cmax == ri
78
80
  @hsv = [60 * (((gi - bi) / delta) % 6)]
79
81
  elsif cmax == gi
80
- @hsv = [60 * (((bi - ri)/ delta) + 2)]
82
+ @hsv = [60 * (((bi - ri) / delta) + 2)]
81
83
  elsif cmax == bi
82
- @hsv = [60 * (((ri - gi)/ delta) + 4)]
84
+ @hsv = [60 * (((ri - gi) / delta) + 4)]
83
85
  end
84
86
 
85
87
  # Saturation calculation
86
- if (cmax == 0)
87
- @hsv << 0
88
- else
89
- @hsv << delta / cmax
90
- end
88
+ @hsv << if cmax.zero?
89
+ 0
90
+ else
91
+ delta / cmax
92
+ end
91
93
 
92
94
  # Value calculation
93
95
  @hsv << cmax
@@ -1,6 +1,7 @@
1
- require 'rmagick'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Camalian
4
+ # Load image into Camalian
4
5
  class Image
5
6
  attr_accessor :src_file_path
6
7
 
@@ -8,29 +9,30 @@ module Camalian
8
9
  @src_file_path = file_path
9
10
  end
10
11
 
11
- def prominent_colors(count=Camalian.options[:color_count])
12
- image = ::Magick::Image.read(@src_file_path)[0]
13
- image.resize!(100,100)
14
- colors = Palette.new
15
- initial_count = count
16
- q = nil
17
- loop do
18
- q = image.quantize(initial_count, Magick::RGBColorspace)
19
- break if q.color_histogram.size > count
20
- initial_count = initial_count + 10
12
+ def prominent_colors(count = Camalian.options[:color_count],
13
+ quantization: Camalian.options[:quantization],
14
+ optimal: true)
15
+ image = ::ChunkyPNG::Image.from_file(@src_file_path)
16
+
17
+ colors = image.pixels.map do |val|
18
+ Color.new(
19
+ ChunkyPNG::Color.r(val),
20
+ ChunkyPNG::Color.g(val),
21
+ ChunkyPNG::Color.b(val)
22
+ )
21
23
  end
22
- palette = q.color_histogram.sort {|a, b| b[1] <=> a[1]}
23
- (0..[count, palette.count].min - 1).each do |i|
24
- c = palette[i].first.to_s.split(',').map {|x| x[/\d+/]}
25
- c.pop
26
- c[0], c[1], c[2] = [c[0], c[1], c[2]].map { |s|
27
- s = s.to_i
28
- s = s / 256 if s / 256 > 0 # not all ImageMagicks are created equal....
29
- s
30
- }
31
- colors << Color.new(c[0],c[1],c[2])
24
+
25
+ quantize = Object.const_get("Camalian::Quantization::#{quantization.capitalize}").new
26
+
27
+ palette = quantize.process(colors, count)
28
+
29
+ retry_count = 1
30
+ while !optimal && palette.size < count
31
+ palette = quantize.process(colors, count + retry_count)
32
+ retry_count += 1
32
33
  end
33
- return colors.uniq(&:to_hex)
34
+
35
+ palette
34
36
  end
35
37
  end
36
38
  end
@@ -1,26 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Camalian
4
+ # Collection of colors with some useful features
2
5
  class Palette < Array
3
-
4
6
  def sort_by_lightness
5
- Palette.new(self.sort_by { |a| a.l }.reverse)
7
+ Palette.new(sort_by(&:l).reverse)
6
8
  end
7
9
 
8
10
  def sort_by_hue
9
- Palette.new(self.sort_by { |a| a.h }.reverse)
11
+ Palette.new(sort_by(&:h).reverse)
10
12
  end
11
13
 
12
14
  def sort_similar_colors
13
- Palette.new(self.sort_by { |a| a.hsv })
15
+ Palette.new(sort_by(&:hsv))
14
16
  end
15
17
 
16
18
  def sort_by_saturation
17
- Palette.new(self.sort_by { |a| a.s }.reverse)
19
+ Palette.new(sort_by(&:s).reverse)
20
+ end
21
+
22
+ def average_color
23
+ r = map(&:r).inject(&:+)
24
+ g = map(&:g).inject(&:+)
25
+ b = map(&:b).inject(&:+)
26
+ size = self.size
27
+
28
+ Color.new(r / size, g / size, b / size)
18
29
  end
19
30
 
20
31
  def light_colors(limit1, limit2)
21
32
  min = [limit1, limit2].min
22
33
  max = [limit1, limit2].max
23
- table = self.dup
34
+ table = dup
24
35
  Palette.new(table.delete_if { |color| color.l > max or color.l < min })
25
36
  end
26
37
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Camalian
4
+ module Quantization
5
+ class Histogram # :nodoc:
6
+ def process(colors, count)
7
+ bucket_size = (255.0 / count).ceil
8
+ buckets = {}
9
+
10
+ colors.each do |color|
11
+ key = bucket_key(color, bucket_size)
12
+ buckets[key] ||= Palette.new
13
+ buckets[key].push(color)
14
+ end
15
+
16
+ Palette.new(buckets.map { |_, value| value.average_color })
17
+ end
18
+
19
+ private
20
+
21
+ def bucket_key(color, bucket_size)
22
+ "#{color.r / bucket_size}:#{color.g / bucket_size}:#{color.b / bucket_size}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Camalian
2
- VERSION = "0.0.3"
4
+ VERSION = '0.1.0'
3
5
  end
Binary file
@@ -1,29 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
1
4
  require 'minitest/autorun'
2
5
  require 'minitest/spec'
3
6
  require 'camalian'
4
7
 
5
8
  describe Camalian::Color do
6
9
  before do
7
- @color = Camalian::Color.new(120,255,30)
10
+ @color = Camalian::Color.new(120, 255, 30)
8
11
  end
9
12
 
10
- describe "Color initialized with 120, 255, 30 rgb values" do
11
- it "hex value must be #78ff1e" do
12
- @color.to_hex.must_equal "#78ff1e"
13
+ describe 'Color initialized with 120, 255, 30 rgb values' do
14
+ it 'hex value must be #78ff1e' do
15
+ _(@color.to_hex).must_equal '#78ff1e'
13
16
  end
14
17
 
15
- it "hsl color components must " do
16
- [@color.h.to_i, @color.s.to_i, @color.l.to_i].must_equal [96, 100, 55]
18
+ it 'hsl color components must ' do
19
+ _([@color.h.to_i, @color.s.to_i, @color.l.to_i]).must_equal [96, 100, 55]
17
20
  end
18
21
 
19
- it "hsv color components must " do
20
- @color.hsv.map(&:to_i).must_equal [96, 88, 100]
22
+ it 'hsv color components must ' do
23
+ _(@color.hsv.map(&:to_i)).must_equal [96, 88, 100]
21
24
  end
22
25
  end
23
26
 
24
- describe "initialized with 1 integer rgb value" do
25
- it "must have leading zero" do
26
- Camalian::Color.new(7, 7, 7).to_hex.must_equal "#070707"
27
+ describe 'initialized with 1 integer rgb value' do
28
+ it 'must have leading zero' do
29
+ _(Camalian::Color.new(7, 7, 7).to_hex).must_equal '#070707'
27
30
  end
28
31
  end
29
32
  end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start
@@ -1,28 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
1
4
  require 'minitest/autorun'
2
5
  require 'minitest/spec'
3
6
  require 'camalian'
4
7
 
5
- describe Camalian::Image do
6
-
7
- end
8
+ PALLET_IMAGE_COLORS = %w[#4dd915 #49cc23 #45c031 #41b43f #3da84d #399c5b #359069 #318478 #2d7886 #296c94 #2560a2
9
+ #2154b0 #1d48be #193ccc #1530db].freeze
8
10
 
9
11
  describe Camalian::Palette do
10
12
  before do
11
- @image = Camalian::load( File.join( File.dirname(__FILE__), 'assets/palette.png'))
12
- @palette = @image.prominent_colors(15)
13
+ @image = Camalian.load(File.join(File.dirname(__FILE__), 'assets/palette.png'))
14
+ @palette = @image.prominent_colors(15, optimal: false)
13
15
  end
14
16
 
15
- describe "palette with 15 colors extracted" do
16
- it "must have 15 colors" do
17
- @palette.size.must_equal 15
17
+ describe 'palette with 15 colors extracted' do
18
+ it 'must have 15 colors' do
19
+ _(@palette.size).must_equal 15
18
20
  end
19
21
 
20
- it "sort similar colors in order" do
21
- @palette.sort_similar_colors.map(&:to_hex).must_equal %W(#4dda15 #45c131 #41b53f #3da94d #3da84e #359169 #318578 #2d7986 #296d94 #2560a3 #2154b1 #1d48bf #193dcd #193cce #1530dc)
22
+ it 'sort similar colors in order' do
23
+ _(@palette.sort_similar_colors.map(&:to_hex)).must_equal PALLET_IMAGE_COLORS
22
24
  end
23
25
 
24
- it "color with intensity 0-40 works well" do
25
- @palette.light_colors(0, 40).map(&:to_hex).must_equal %W(#318578 #2560a3 #359169 #296d94 #2d7986)
26
+ it 'color with intensity 0-40 works well' do
27
+ _(@palette.light_colors(0, 40).map(&:to_hex)).must_equal %w[#2560a2 #296c94 #2d7886 #318478 #359069]
26
28
  end
27
29
  end
28
30
  end
metadata CHANGED
@@ -1,57 +1,75 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camalian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nazar Hussain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-30 00:00:00.000000000 Z
11
+ date: 2020-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: cocaine
14
+ name: chunky_png
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
- version: '0'
22
+ version: 1.3.14
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
- version: '0'
32
+ version: 1.3.14
27
33
  - !ruby/object:Gem::Dependency
28
- name: rmagick
34
+ name: minitest
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: 2.15.4
34
- type: :runtime
39
+ version: '5.14'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 5.14.2
43
+ type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
47
  - - "~>"
39
48
  - !ruby/object:Gem::Version
40
- version: 2.15.4
49
+ version: '5.14'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 5.14.2
41
53
  - !ruby/object:Gem::Dependency
42
- name: oily_png
54
+ name: rake
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
57
  - - "~>"
46
58
  - !ruby/object:Gem::Version
47
- version: 1.2.0
48
- type: :runtime
59
+ version: '13.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 13.0.1
63
+ type: :development
49
64
  prerelease: false
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
67
  - - "~>"
53
68
  - !ruby/object:Gem::Version
54
- version: 1.2.0
69
+ version: '13.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 13.0.1
55
73
  description: Library used to deal with colors and images
56
74
  email:
57
75
  - nazarhussain@gmail.com
@@ -59,7 +77,14 @@ executables: []
59
77
  extensions: []
60
78
  extra_rdoc_files: []
61
79
  files:
80
+ - ".github/workflows/gpr-push.yml"
81
+ - ".github/workflows/ruby.yml"
82
+ - ".github/workflows/rubygems-push.yml"
62
83
  - ".gitignore"
84
+ - ".overcommit.yml"
85
+ - ".rubocop.yml"
86
+ - ".tool-versions"
87
+ - ".travis.yml"
63
88
  - Gemfile
64
89
  - LICENSE.txt
65
90
  - README.md
@@ -69,10 +94,11 @@ files:
69
94
  - lib/camalian/color.rb
70
95
  - lib/camalian/image.rb
71
96
  - lib/camalian/palette.rb
97
+ - lib/camalian/quantization/histogram.rb
72
98
  - lib/camalian/version.rb
73
- - lib/chunky_png_patch/color.rb
74
99
  - test/assets/palette.png
75
100
  - test/test_color.rb
101
+ - test/test_helper.rb
76
102
  - test/test_palette.rb
77
103
  homepage: https://github.com/nazarhussain/camalian
78
104
  licenses:
@@ -86,16 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
112
  requirements:
87
113
  - - ">="
88
114
  - !ruby/object:Gem::Version
89
- version: '0'
115
+ version: '2.4'
90
116
  required_rubygems_version: !ruby/object:Gem::Requirement
91
117
  requirements:
92
118
  - - ">="
93
119
  - !ruby/object:Gem::Version
94
120
  version: '0'
95
- requirements:
96
- - ImageMagick
97
- rubyforge_project:
98
- rubygems_version: 2.4.5
121
+ requirements: []
122
+ rubygems_version: 3.0.3
99
123
  signing_key:
100
124
  specification_version: 4
101
125
  summary: Library used to deal with colors and images. You can extract colors from
@@ -103,4 +127,5 @@ summary: Library used to deal with colors and images. You can extract colors fro
103
127
  test_files:
104
128
  - test/assets/palette.png
105
129
  - test/test_color.rb
130
+ - test/test_helper.rb
106
131
  - test/test_palette.rb
@@ -1,14 +0,0 @@
1
- module ChunkyPNG::Color
2
- # See http://en.wikipedia.org/wiki/Hue#Computing_hue_from_RGB
3
- def self.hue(pixel)
4
- r, g, b = r(pixel), g(pixel), b(pixel)
5
- return 0 if r == b and b == g
6
- ((180 / Math::PI * Math.atan2((2 * r) - g - b, Math.sqrt(3) * (g - b))) - 90) % 360
7
- end
8
-
9
- # The modular distance, as the hue is circular
10
- def self.distance(pixel, poxel)
11
- hue_pixel, hue_poxel = hue(pixel), hue(poxel)
12
- [(hue_pixel - hue_poxel) % 360, (hue_poxel - hue_pixel) % 360].min
13
- end
14
- end