camalian 0.0.3 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/gpr-push.yml +30 -0
- data/.github/workflows/ruby.yml +32 -0
- data/.github/workflows/rubygems-push.yml +29 -0
- data/.gitignore +2 -1
- data/.overcommit.yml +33 -0
- data/.rubocop.yml +37 -0
- data/.tool-versions +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +6 -0
- data/README.md +45 -5
- data/Rakefile +6 -3
- data/camalian.gemspec +16 -15
- data/lib/camalian.rb +20 -14
- data/lib/camalian/color.rb +47 -34
- data/lib/camalian/image.rb +24 -22
- data/lib/camalian/palette.rb +24 -5
- data/lib/camalian/quantization/histogram.rb +29 -0
- data/lib/camalian/quantization/k_means.rb +59 -0
- data/lib/camalian/quantization/median_cut.rb +74 -0
- data/lib/camalian/version.rb +3 -1
- data/test/assets/palette.png +0 -0
- data/test/color_test.rb +32 -0
- data/test/palette_test.rb +64 -0
- data/test/quantization/histogram_test.rb +61 -0
- data/test/quantization/k_means_test.rb +61 -0
- data/test/quantization/median_cut_test.rb +63 -0
- data/test/test_helper.rb +11 -0
- metadata +56 -23
- data/lib/chunky_png_patch/color.rb +0 -14
- data/test/test_color.rb +0 -29
- data/test/test_palette.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5b9de2c66339ca8ad016f7008d1737b6015bf0a69c5ebfb420d31f4183a52257
|
4
|
+
data.tar.gz: 8280252df27703b1bb26bbbb86ba8af9749c7e9daefb5ed4b6c74db445273777
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6220b18f426c0a30240a98afb98e1217d9aab1947051c9b305a5b7f6d413e71c4a8ef7420ecafed128eab0428fd28f9ee2e844ad30d06fa80fa5a1d2900b9cfa
|
7
|
+
data.tar.gz: 8e7d6b392ffda8cf50dfbbdec3bdf75bfd050d7f50618b0236cb1848e6802d0fc8abaed7c522c263f533a9be67108d866679a176f80ca88db6e27e9aa5e063f2
|
@@ -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-latest
|
19
|
+
strategy:
|
20
|
+
matrix:
|
21
|
+
ruby: ["2.5", "2.6", "2.7"]
|
22
|
+
name: Ruby ${{ matrix.ruby }}
|
23
|
+
steps:
|
24
|
+
- uses: actions/checkout@v2
|
25
|
+
- name: Set up Ruby ${{ matrix.ruby }}
|
26
|
+
uses: ruby/setup-ruby@v1
|
27
|
+
with:
|
28
|
+
ruby-version: ${{ matrix.ruby }}
|
29
|
+
- name: Install dependencies
|
30
|
+
run: bundle install
|
31
|
+
- name: Run tests
|
32
|
+
run: bundle exec rake
|
@@ -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
data/.overcommit.yml
ADDED
@@ -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
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,37 @@
|
|
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/BlockLength:
|
31
|
+
Exclude:
|
32
|
+
- test/**/*
|
33
|
+
|
34
|
+
Metrics/AbcSize:
|
35
|
+
Max: 30
|
36
|
+
IgnoredMethods:
|
37
|
+
- build_components
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.7.3
|
data/.travis.yml
ADDED
@@ -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
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.
|
13
|
+
gem 'camalian', '~> 0.2.2'
|
10
14
|
|
11
15
|
And then execute:
|
12
16
|
|
@@ -18,10 +22,46 @@ Or install it yourself as:
|
|
18
22
|
|
19
23
|
## Usage
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
```ruby
|
26
|
+
image = Camalian::load('file_path')
|
27
|
+
colors = image.prominent_colors(15)
|
28
|
+
colors = colors.sort_similar_colors
|
29
|
+
colors.light_colors(0, 40)
|
30
|
+
```
|
31
|
+
|
32
|
+
You can find a working example with detail explanation and reference code here on [this link](https://basicdrift.com/color-extraction-library-build-color-search-engine-fdf369678d5a). Here we will build a functional color based image search engine in Ruby on Rails.
|
33
|
+
|
34
|
+
NOTE: Since its a compute intensive operation so for production use its suggested to use under a background job and not within a request/response cycle.
|
35
|
+
|
36
|
+
## Quantization Algorithms
|
37
|
+
|
38
|
+
Currently following algorithms are implemented.
|
39
|
+
|
40
|
+
### Histogram
|
41
|
+
|
42
|
+
Its a most common algorithm for color quantization and used different bucket technique to group the colors together. You can read more about this [technique here](https://en.wikipedia.org/wiki/Color_histogram). It can be accessed by `Camalian::QUANTIZATION_HISTOGRAM` constant. This is used as default method as well.
|
43
|
+
|
44
|
+
### K Means
|
45
|
+
|
46
|
+
This algorithm uses color distancing in RGB space to group the similar colors. You can learn more about this [technique here](https://en.wikipedia.org/wiki/K-means_clustering). It can be accessed by `Camalian::QUANTIZATION_K_MEANS` constant.
|
47
|
+
|
48
|
+
### Median Cut
|
49
|
+
|
50
|
+
This algorithm uses color highest color range to determine the median and split colors to groups. The output consists of average color of such color groups. Since these algorithm don't use actual colors and instead average, so you will may not exact matching pixel in the image. This algorithm is nice to be used with image compression, where similarity and compression is important than having same pixel colors. You can learn more about this [technique here](https://tpgit.github.io/UnOfficialLeptDocs/leptonica/color-quantization.html) . It can be accessed by `Camalian::QUANTIZATION_MEDIAN_CUT` constant.
|
51
|
+
|
52
|
+
|
53
|
+
You can set default quantization method globally as:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
Camalian.options[:quantization] = Camalian::QUANTIZATION_K_MEANS
|
57
|
+
```
|
58
|
+
|
59
|
+
or you can set at the time of extracting colors by.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
image = Camalian::load('file_path')
|
63
|
+
colors = image.prominent_colors(15, quantization: Camalian::QUANTIZATION_K_MEANS)
|
64
|
+
```
|
25
65
|
|
26
66
|
## Contributing
|
27
67
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
2
4
|
|
3
5
|
require 'rake/testtask'
|
4
6
|
|
5
7
|
Rake::TestTask.new do |t|
|
6
8
|
t.libs << 'test'
|
9
|
+
t.pattern = 'test/**/*_test.rb'
|
7
10
|
end
|
8
11
|
|
9
|
-
desc
|
10
|
-
task :
|
12
|
+
desc 'Run tests'
|
13
|
+
task default: :test
|
data/camalian.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
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 =
|
8
|
+
spec.name = 'camalian'
|
8
9
|
spec.version = Camalian::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
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 = [
|
20
|
+
spec.require_paths = ['lib']
|
20
21
|
|
21
|
-
spec.
|
22
|
+
spec.add_dependency 'chunky_png', '~> 1.3', '>= 1.3.14'
|
22
23
|
|
23
|
-
spec.
|
24
|
-
spec.
|
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.5'
|
27
28
|
end
|
data/lib/camalian.rb
CHANGED
@@ -1,25 +1,31 @@
|
|
1
|
-
|
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
|
8
|
-
require
|
9
|
-
require
|
10
|
-
|
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
|
+
require 'camalian/quantization/k_means'
|
13
|
+
require 'camalian/quantization/median_cut'
|
14
|
+
|
15
|
+
module Camalian # :nodoc:
|
16
|
+
QUANTIZATION_HISTOGRAM = Camalian::Quantization::Histogram
|
17
|
+
QUANTIZATION_K_MEANS = Camalian::Quantization::KMeans
|
18
|
+
QUANTIZATION_MEDIAN_CUT = Camalian::Quantization::MedianCut
|
11
19
|
|
12
|
-
module Camalian
|
13
20
|
class << self
|
14
21
|
def options
|
15
|
-
convert = `which convert`.strip
|
16
22
|
@options ||= {
|
17
|
-
|
18
|
-
|
23
|
+
color_count: 8,
|
24
|
+
quantization: Camalian::QUANTIZATION_HISTOGRAM
|
19
25
|
}
|
20
26
|
end
|
21
27
|
|
22
|
-
def load(image_path)
|
28
|
+
def load(image_path)
|
23
29
|
Image.new(image_path)
|
24
30
|
end
|
25
31
|
end
|
data/lib/camalian/color.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
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(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def initialize(r, g, b)
|
9
|
+
build_components(r, g, b)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_hex(hex_value)
|
13
|
+
color_hash = hex_value[0..6]
|
14
|
+
color_hash = color_hash[1..6] if color_hash[0] == '#'
|
15
|
+
r = color_hash[0..1].to_i(16)
|
16
|
+
g = color_hash[2..3].to_i(16)
|
17
|
+
b = color_hash[4..5].to_i(16)
|
18
|
+
|
19
|
+
Color.new(r, g, b)
|
13
20
|
end
|
14
21
|
|
15
22
|
def to_s
|
@@ -20,22 +27,28 @@ module Camalian
|
|
20
27
|
"##{r.to_s(16).rjust(2, '0')}#{g.to_s(16).rjust(2, '0')}#{b.to_s(16).rjust(2, '0')}"
|
21
28
|
end
|
22
29
|
|
23
|
-
|
24
|
-
|
30
|
+
# Used for array uniqueness
|
31
|
+
def hash
|
32
|
+
"#{r}#{g}#{b}".to_i
|
25
33
|
end
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
# Used for object comparison
|
36
|
+
def ==(other)
|
37
|
+
r == other.r && g == other.g && b == other.b
|
38
|
+
end
|
39
|
+
alias eql? ==
|
40
|
+
|
41
|
+
def hue_distance(color)
|
42
|
+
[(h - color.h) % 360, (color.h - h) % 360].min
|
43
|
+
end
|
44
|
+
|
45
|
+
def rgb_distance(color)
|
46
|
+
Math.sqrt(((r - color.r)**2) + ((g - color.g)**2) + ((b - color.b)**2))
|
34
47
|
end
|
35
48
|
|
36
49
|
private
|
37
50
|
|
38
|
-
def build_components(r,g,b)
|
51
|
+
def build_components(r, g, b)
|
39
52
|
@r = r
|
40
53
|
@g = g
|
41
54
|
@b = b
|
@@ -50,21 +63,21 @@ module Camalian
|
|
50
63
|
|
51
64
|
@l = (cmax + cmin) / 2.0
|
52
65
|
|
53
|
-
if delta
|
66
|
+
if delta.zero?
|
54
67
|
@h = 0
|
55
68
|
elsif cmax == ri
|
56
69
|
@h = 60 * (((gi - bi) / delta) % 6)
|
57
70
|
elsif cmax == gi
|
58
|
-
@h = 60 * (((bi - ri)/ delta) + 2)
|
71
|
+
@h = 60 * (((bi - ri) / delta) + 2)
|
59
72
|
elsif cmax == bi
|
60
|
-
@h = 60 * (((ri - gi)/ delta) + 4)
|
73
|
+
@h = 60 * (((ri - gi) / delta) + 4)
|
61
74
|
end
|
62
75
|
|
63
|
-
if
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
76
|
+
@s = if delta.zero?
|
77
|
+
0
|
78
|
+
else
|
79
|
+
delta / (1 - (2 * @l - 1).abs)
|
80
|
+
end
|
68
81
|
|
69
82
|
@h = @h.round(2)
|
70
83
|
@s = (@s * 100).round(2)
|
@@ -72,22 +85,22 @@ module Camalian
|
|
72
85
|
|
73
86
|
# HSV Calculation
|
74
87
|
# Hue calculation
|
75
|
-
if delta
|
88
|
+
if delta.zero?
|
76
89
|
@hsv = [0]
|
77
90
|
elsif cmax == ri
|
78
91
|
@hsv = [60 * (((gi - bi) / delta) % 6)]
|
79
92
|
elsif cmax == gi
|
80
|
-
@hsv = [60 * (((bi - ri)/ delta) + 2)]
|
93
|
+
@hsv = [60 * (((bi - ri) / delta) + 2)]
|
81
94
|
elsif cmax == bi
|
82
|
-
@hsv = [60 * (((ri - gi)/ delta) + 4)]
|
95
|
+
@hsv = [60 * (((ri - gi) / delta) + 4)]
|
83
96
|
end
|
84
97
|
|
85
98
|
# Saturation calculation
|
86
|
-
if
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
99
|
+
@hsv << if cmax.zero?
|
100
|
+
0
|
101
|
+
else
|
102
|
+
delta / cmax
|
103
|
+
end
|
91
104
|
|
92
105
|
# Value calculation
|
93
106
|
@hsv << cmax
|