colordom 0.2.0 → 0.3.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 +4 -4
- data/README.md +1 -1
- data/ext/colordom/Cargo.lock +1036 -0
- data/{Cargo.toml → ext/colordom/Cargo.toml} +1 -0
- data/ext/colordom/extconf.rb +6 -0
- data/ext/colordom/src/lib.rs +156 -0
- data/lib/colordom/color.rb +40 -16
- data/lib/colordom/error.rb +2 -0
- data/lib/colordom/image.rb +27 -0
- data/lib/colordom/version.rb +3 -1
- data/lib/colordom.rb +35 -39
- metadata +14 -37
- data/.gitignore +0 -17
- data/.travis.yml +0 -13
- data/Gemfile +0 -11
- data/Rakefile +0 -13
- data/bin/benchmark +0 -80
- data/bin/compare +0 -68
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/colordom.gemspec +0 -29
- data/ext/Rakefile +0 -10
- data/lib/colordom/native.rb +0 -16
- data/lib/colordom/result.rb +0 -9
- data/src/lib.rs +0 -99
@@ -0,0 +1,156 @@
|
|
1
|
+
use std::path::PathBuf;
|
2
|
+
|
3
|
+
use magnus::{
|
4
|
+
class, define_module, function, method,
|
5
|
+
prelude::*, gc::register_mark_object, memoize,
|
6
|
+
Error, ExceptionClass, RClass, RModule
|
7
|
+
};
|
8
|
+
|
9
|
+
use image::{DynamicImage};
|
10
|
+
use palette_extract::{Quality, MaxColors, PixelEncoding, PixelFilter};
|
11
|
+
use palette::{FromColor, IntoColor, Lab, Pixel, Srgb};
|
12
|
+
|
13
|
+
use dominant_color;
|
14
|
+
use kmeans_colors;
|
15
|
+
|
16
|
+
fn colordom_error() -> ExceptionClass {
|
17
|
+
*memoize!(ExceptionClass: {
|
18
|
+
let ex: RClass = class::object().const_get::<_, RModule>("Colordom").unwrap().const_get("Error").unwrap();
|
19
|
+
register_mark_object(ex);
|
20
|
+
|
21
|
+
ExceptionClass::from_value(*ex).unwrap()
|
22
|
+
})
|
23
|
+
}
|
24
|
+
|
25
|
+
#[derive(Clone)]
|
26
|
+
#[magnus::wrap(class = "Colordom::Color", free_immediatly, size)]
|
27
|
+
struct Color {
|
28
|
+
r: u8,
|
29
|
+
g: u8,
|
30
|
+
b: u8
|
31
|
+
}
|
32
|
+
|
33
|
+
impl Color {
|
34
|
+
fn new(r: u8, g: u8, b: u8) -> Self {
|
35
|
+
Self { r, g, b }
|
36
|
+
}
|
37
|
+
|
38
|
+
fn r(&self) -> u8 { self.r }
|
39
|
+
fn g(&self) -> u8 { self.g }
|
40
|
+
fn b(&self) -> u8 { self.b }
|
41
|
+
|
42
|
+
fn rgb(&self) -> Vec<u8> {
|
43
|
+
vec![self.r, self.g, self.b]
|
44
|
+
}
|
45
|
+
|
46
|
+
fn hex(&self) -> String {
|
47
|
+
format!("#{:02X}{:02X}{:02X}", self.r, self.g, self.b)
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
#[derive(Clone)]
|
52
|
+
#[magnus::wrap(class = "Colordom::Image", free_immediatly, size)]
|
53
|
+
struct Image {
|
54
|
+
img: DynamicImage
|
55
|
+
}
|
56
|
+
|
57
|
+
impl Image {
|
58
|
+
fn new(path: PathBuf) -> Result<Self, Error> {
|
59
|
+
match image::open(&path) {
|
60
|
+
Ok(img) => Ok(Self { img }),
|
61
|
+
Err(ex) => Err(Error::new(colordom_error(), ex.to_string()))
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
fn pixels(&self) -> &[u8] {
|
66
|
+
self.img.as_bytes()
|
67
|
+
}
|
68
|
+
|
69
|
+
fn has_alpha(&self) -> bool {
|
70
|
+
self.img.color().has_alpha()
|
71
|
+
}
|
72
|
+
|
73
|
+
fn histogram(&self, max_colors: usize) -> Vec<Color> {
|
74
|
+
let colors = dominant_color::get_colors(
|
75
|
+
&self.pixels(),
|
76
|
+
self.has_alpha()
|
77
|
+
);
|
78
|
+
|
79
|
+
colors.chunks(3)
|
80
|
+
.take(max_colors)
|
81
|
+
.map(|x| Color::new(x[0], x[1], x[2]))
|
82
|
+
.collect::<Vec<Color>>()
|
83
|
+
}
|
84
|
+
|
85
|
+
fn mediancut(&self, max_colors: usize) -> Vec<Color> {
|
86
|
+
let colors = palette_extract::get_palette_with_options(
|
87
|
+
&self.pixels(),
|
88
|
+
PixelEncoding::Rgb,
|
89
|
+
Quality::new(6),
|
90
|
+
MaxColors::new(max_colors as u8),
|
91
|
+
PixelFilter::None
|
92
|
+
);
|
93
|
+
|
94
|
+
colors.iter()
|
95
|
+
.take(max_colors)
|
96
|
+
.map(|x| Color::new(x.r, x.g, x.b))
|
97
|
+
.collect::<Vec<Color>>()
|
98
|
+
}
|
99
|
+
|
100
|
+
fn kmeans(&self, max_colors: usize) -> Vec<Color> {
|
101
|
+
let max_iterations = 20;
|
102
|
+
let converge = 1.0;
|
103
|
+
let verbose = false;
|
104
|
+
let seed = 0;
|
105
|
+
|
106
|
+
let lab: Vec<Lab> = Srgb::from_raw_slice(&self.pixels()).iter()
|
107
|
+
.map(|x| x.into_format().into_color())
|
108
|
+
.collect();
|
109
|
+
|
110
|
+
let result = kmeans_colors::get_kmeans_hamerly(
|
111
|
+
max_colors, max_iterations, converge, verbose, &lab, seed
|
112
|
+
);
|
113
|
+
|
114
|
+
let colors = &result.centroids.iter()
|
115
|
+
.map(|x| Srgb::from_color(*x).into_format())
|
116
|
+
.collect::<Vec<Srgb<u8>>>();
|
117
|
+
|
118
|
+
colors.iter()
|
119
|
+
.take(max_colors)
|
120
|
+
.map(|x| Color::new(x.red, x.green, x.blue))
|
121
|
+
.collect::<Vec<Color>>()
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
#[magnus::init]
|
126
|
+
fn init() -> Result<(), Error> {
|
127
|
+
let module = define_module("Colordom")?;
|
128
|
+
|
129
|
+
let colorc = module.define_class("Color", Default::default())?;
|
130
|
+
|
131
|
+
colorc.define_singleton_method("new", function!(Color::new, 3))?;
|
132
|
+
colorc.define_method("r", method!(Color::r, 0))?;
|
133
|
+
colorc.define_method("g", method!(Color::g, 0))?;
|
134
|
+
colorc.define_method("b", method!(Color::b, 0))?;
|
135
|
+
|
136
|
+
colorc.define_method("rgb", method!(Color::rgb, 0))?;
|
137
|
+
colorc.define_method("hex", method!(Color::hex, 0))?;
|
138
|
+
|
139
|
+
colorc.define_method("clone", method!(Color::clone, 0))?;
|
140
|
+
colorc.define_method("dup", method!(Color::clone, 0))?;
|
141
|
+
|
142
|
+
colorc.define_alias("to_rgb", "rgb")?;
|
143
|
+
colorc.define_alias("to_hex", "hex")?;
|
144
|
+
|
145
|
+
let imagec = module.define_class("Image", Default::default())?;
|
146
|
+
|
147
|
+
imagec.define_singleton_method("new", function!(Image::new, 1))?;
|
148
|
+
imagec.define_method("histogram", method!(Image::histogram, 1))?;
|
149
|
+
imagec.define_method("mediancut", method!(Image::mediancut, 1))?;
|
150
|
+
imagec.define_method("kmeans", method!(Image::kmeans, 1))?;
|
151
|
+
|
152
|
+
imagec.define_method("clone", method!(Image::clone, 0))?;
|
153
|
+
imagec.define_method("dup", method!(Image::clone, 0))?;
|
154
|
+
|
155
|
+
Ok(())
|
156
|
+
}
|
data/lib/colordom/color.rb
CHANGED
@@ -1,25 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Colordom
|
4
|
+
# Color object with RGB and HEX values implemented in Rust.
|
2
5
|
class Color
|
3
|
-
|
6
|
+
# @!method initialize(r, g, b)
|
7
|
+
# A new instance of Color.
|
8
|
+
# @return [Color]
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
# @!attribute [r] r
|
11
|
+
# Red color value.
|
12
|
+
# @return [Integer]
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
14
|
+
# @!attribute [r] g
|
15
|
+
# Green color value.
|
16
|
+
# @return [Integer]
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
# @!attribute [r] b
|
19
|
+
# Blue color value.
|
20
|
+
# @return [Integer]
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
# @!method rgb
|
23
|
+
# @!parse [ruby] alias to_rgb rgb
|
24
|
+
# Get the RGB representation of the color.
|
25
|
+
# @return [Array<Integer>]
|
26
|
+
|
27
|
+
# @!method hex
|
28
|
+
# @!parse [ruby] alias to_hex hex
|
29
|
+
# Get the hex representation of the color.
|
30
|
+
# @return [String]
|
31
|
+
|
32
|
+
# Compare with other color value.
|
33
|
+
# @param other [Color, Array<Integer>, String]
|
34
|
+
# @return [Boolean]
|
21
35
|
|
22
|
-
|
23
|
-
|
36
|
+
def ==(other)
|
37
|
+
case other
|
38
|
+
when Array
|
39
|
+
rgb == other
|
40
|
+
when String
|
41
|
+
hex == other
|
42
|
+
when self.class
|
43
|
+
rgb == other.rgb
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
24
48
|
end
|
25
49
|
end
|
data/lib/colordom/error.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Colordom
|
4
|
+
# Image object implemented in Rust that extracts dominant colors.
|
5
|
+
class Image
|
6
|
+
# @!method initialize(path)
|
7
|
+
# A new instance of Image.
|
8
|
+
# @param path [String, Pathname, File]
|
9
|
+
# @return [Image]
|
10
|
+
# @raise [Error] if path is not a valid image
|
11
|
+
|
12
|
+
# @!method histogram(max_colors)
|
13
|
+
# Get dominant colors using histogram quantization.
|
14
|
+
# @param max_colors [Integer]
|
15
|
+
# @return [Array<Color>]
|
16
|
+
|
17
|
+
# @!method mediancut(max_colors)
|
18
|
+
# Get dominant colors using media cut quantization.
|
19
|
+
# @param max_colors [Integer]
|
20
|
+
# @return [Array<Color>]
|
21
|
+
|
22
|
+
# @!method kmeans(max_colors)
|
23
|
+
# Get dominant colors using k-means clustering.
|
24
|
+
# @param max_colors [Integer]
|
25
|
+
# @return [Array<Color>]
|
26
|
+
end
|
27
|
+
end
|
data/lib/colordom/version.rb
CHANGED
data/lib/colordom.rb
CHANGED
@@ -1,56 +1,52 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
5
|
+
require "colordom/#{$1}/colordom"
|
6
|
+
rescue LoadError
|
7
|
+
require 'colordom/colordom'
|
8
|
+
end
|
2
9
|
|
3
|
-
require 'colordom/result'
|
4
|
-
require 'colordom/native'
|
5
10
|
require 'colordom/error'
|
6
11
|
require 'colordom/color'
|
12
|
+
require 'colordom/image'
|
7
13
|
require 'colordom/version'
|
8
14
|
|
15
|
+
# Module that extracts dominant colors from images
|
16
|
+
# using native extension implemented in Rust.
|
9
17
|
module Colordom
|
10
18
|
class << self
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def mediancut(path, max_colors = 5)
|
19
|
-
regex = /r: (\d+), g: (\d+), b: (\d+)/
|
20
|
-
value = call(:to_mediancut, path, max_colors)
|
21
|
-
|
22
|
-
parse(value, regex, max_colors)
|
23
|
-
end
|
19
|
+
# Get dominant colors using histogram quantization.
|
20
|
+
# @param path (see Image#initialize)
|
21
|
+
# @param max_colors (see Image#histogram)
|
22
|
+
# @return (see Image#histogram)
|
23
|
+
# @raise (see Image#initialize)
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
parse(value, regex)
|
25
|
+
def histogram(path, max_colors = 5)
|
26
|
+
image = Image.new(path)
|
27
|
+
image.histogram(max_colors)
|
30
28
|
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
result = Native.send(method, path, *args)
|
38
|
-
result = result.read_string.force_encoding('UTF-8')
|
30
|
+
# Get dominant colors using media cut quantization.
|
31
|
+
# @param path (see Image#initialize)
|
32
|
+
# @param max_colors (see Image#mediancut)
|
33
|
+
# @return (see Image#mediancut)
|
34
|
+
# @raise (see Image#initialize)
|
39
35
|
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def mediancut(path, max_colors = 5)
|
37
|
+
image = Image.new(path)
|
38
|
+
image.mediancut(max_colors)
|
43
39
|
end
|
44
40
|
|
45
|
-
|
46
|
-
|
41
|
+
# Get dominant colors using k-means clustering.
|
42
|
+
# @param path (see Image#initialize)
|
43
|
+
# @param max_colors (see Image#kmeans)
|
44
|
+
# @return (see Image#kmeans)
|
45
|
+
# @raise (see Image#initialize)
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
colors.map do |values|
|
52
|
-
Color.new(*values)
|
53
|
-
end
|
47
|
+
def kmeans(path, max_colors = 5)
|
48
|
+
image = Image.new(path)
|
49
|
+
image.kmeans(max_colors)
|
54
50
|
end
|
55
51
|
end
|
56
52
|
end
|
metadata
CHANGED
@@ -1,31 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: colordom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonian Guveli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: thermite
|
14
|
+
name: rb_sys
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ">="
|
@@ -67,48 +53,39 @@ dependencies:
|
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '5.0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
56
|
+
name: rake-compiler
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '1.2'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '1.2'
|
83
69
|
description: Extract dominant colors from images using native extension implemented
|
84
70
|
in Rust.
|
85
71
|
email:
|
86
72
|
- jonian@hardpixel.eu
|
87
73
|
executables: []
|
88
74
|
extensions:
|
89
|
-
- ext/
|
75
|
+
- ext/colordom/extconf.rb
|
90
76
|
extra_rdoc_files: []
|
91
77
|
files:
|
92
|
-
- ".gitignore"
|
93
|
-
- ".travis.yml"
|
94
|
-
- Cargo.toml
|
95
|
-
- Gemfile
|
96
78
|
- LICENSE.txt
|
97
79
|
- README.md
|
98
|
-
-
|
99
|
-
-
|
100
|
-
-
|
101
|
-
-
|
102
|
-
- bin/setup
|
103
|
-
- colordom.gemspec
|
104
|
-
- ext/Rakefile
|
80
|
+
- ext/colordom/Cargo.lock
|
81
|
+
- ext/colordom/Cargo.toml
|
82
|
+
- ext/colordom/extconf.rb
|
83
|
+
- ext/colordom/src/lib.rs
|
105
84
|
- lib/colordom.rb
|
106
85
|
- lib/colordom/color.rb
|
107
86
|
- lib/colordom/error.rb
|
108
|
-
- lib/colordom/
|
109
|
-
- lib/colordom/result.rb
|
87
|
+
- lib/colordom/image.rb
|
110
88
|
- lib/colordom/version.rb
|
111
|
-
- src/lib.rs
|
112
89
|
homepage: https://github.com/hardpixel/colordom
|
113
90
|
licenses:
|
114
91
|
- MIT
|
@@ -121,14 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
98
|
requirements:
|
122
99
|
- - ">="
|
123
100
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
101
|
+
version: '2.6'
|
125
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
103
|
requirements:
|
127
104
|
- - ">="
|
128
105
|
- !ruby/object:Gem::Version
|
129
106
|
version: '0'
|
130
107
|
requirements: []
|
131
|
-
rubygems_version: 3.
|
108
|
+
rubygems_version: 3.3.7
|
132
109
|
signing_key:
|
133
110
|
specification_version: 4
|
134
111
|
summary: Extract dominant colors from images
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: ruby
|
3
|
-
cache: bundler
|
4
|
-
rvm:
|
5
|
-
- 2.7.2
|
6
|
-
env:
|
7
|
-
global:
|
8
|
-
- RUST_VERSION=stable
|
9
|
-
before_install:
|
10
|
-
- if [ ! -e "$HOME/.cargo/bin" ]; then curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain $RUST_VERSION -y; fi
|
11
|
-
- export PATH="$HOME/.cargo/bin:$PATH"
|
12
|
-
- rustup default $RUST_VERSION
|
13
|
-
- gem install bundler -v 2.1.4
|
data/Gemfile
DELETED
data/Rakefile
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'thermite/tasks'
|
4
|
-
|
5
|
-
Thermite::Tasks.new
|
6
|
-
|
7
|
-
Rake::TestTask.new(:test) do |t|
|
8
|
-
t.libs << 'test'
|
9
|
-
t.libs << 'lib'
|
10
|
-
t.test_files = FileList['test/**/*_test.rb']
|
11
|
-
end
|
12
|
-
|
13
|
-
task default: %w[thermite:build test]
|
data/bin/benchmark
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
|
5
|
-
require 'benchmark/ips'
|
6
|
-
require 'benchmark/memory'
|
7
|
-
|
8
|
-
require 'colordom'
|
9
|
-
require 'camalian'
|
10
|
-
require 'colorscore'
|
11
|
-
require 'miro'
|
12
|
-
|
13
|
-
COUNT = 5
|
14
|
-
IMAGE = File.join(__dir__, '..', 'samples/sample.png')
|
15
|
-
|
16
|
-
def miro(method)
|
17
|
-
Miro.options[:color_count] = COUNT
|
18
|
-
Miro.options[:method] = method
|
19
|
-
|
20
|
-
colors = Miro::DominantColors.new(IMAGE)
|
21
|
-
colors.to_hex
|
22
|
-
end
|
23
|
-
|
24
|
-
def colorscore
|
25
|
-
histogram = Colorscore::Histogram.new(IMAGE, COUNT)
|
26
|
-
histogram.colors
|
27
|
-
end
|
28
|
-
|
29
|
-
def camalian(quant)
|
30
|
-
img = Camalian::load(IMAGE)
|
31
|
-
img.prominent_colors(COUNT, quantization: quant)
|
32
|
-
end
|
33
|
-
|
34
|
-
reports = lambda do |x|
|
35
|
-
x.report('colordom (HST)') do
|
36
|
-
Colordom.histogram(IMAGE, COUNT)
|
37
|
-
end
|
38
|
-
|
39
|
-
x.report('colordom (MCQ)') do
|
40
|
-
Colordom.mediancut(IMAGE, COUNT)
|
41
|
-
end
|
42
|
-
|
43
|
-
x.report('colordom (KMS)') do
|
44
|
-
Colordom.kmeans(IMAGE, COUNT)
|
45
|
-
end
|
46
|
-
|
47
|
-
x.report('colorscore (HST)') do
|
48
|
-
colorscore
|
49
|
-
end
|
50
|
-
|
51
|
-
x.report('miro (HST)') do
|
52
|
-
miro('histogram')
|
53
|
-
end
|
54
|
-
|
55
|
-
x.report('miro (PXG)') do
|
56
|
-
miro('pixel_group')
|
57
|
-
end
|
58
|
-
|
59
|
-
x.report('camalian (HST)') do
|
60
|
-
camalian(Camalian::QUANTIZATION_HISTOGRAM)
|
61
|
-
end
|
62
|
-
|
63
|
-
x.report('camalian (MCQ)') do
|
64
|
-
camalian(Camalian::QUANTIZATION_MEDIAN_CUT)
|
65
|
-
end
|
66
|
-
|
67
|
-
x.report('camalian (KMS)') do
|
68
|
-
camalian(Camalian::QUANTIZATION_K_MEANS)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
Benchmark.ips do |x|
|
73
|
-
reports.call(x)
|
74
|
-
x.compare!
|
75
|
-
end
|
76
|
-
|
77
|
-
Benchmark.memory do |x|
|
78
|
-
reports.call(x)
|
79
|
-
x.compare!
|
80
|
-
end
|
data/bin/compare
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
|
5
|
-
require 'tempfile'
|
6
|
-
require 'base64'
|
7
|
-
|
8
|
-
require 'colordom'
|
9
|
-
require 'camalian'
|
10
|
-
require 'colorscore'
|
11
|
-
require 'miro'
|
12
|
-
|
13
|
-
COUNT = 6
|
14
|
-
IMAGE = File.join(__dir__, '..', 'samples/compare.png')
|
15
|
-
TEMPL = File.read File.join(__dir__, '..', 'samples/compare.svg')
|
16
|
-
|
17
|
-
TEMPL.sub!('compare.png', "data:image/png;base64,#{Base64.strict_encode64(File.read(IMAGE))}")
|
18
|
-
|
19
|
-
def replace(prefix, colors)
|
20
|
-
colors.each_with_index do |color, index|
|
21
|
-
TEMPL.sub!("{{#{prefix}-#{index}}}", color)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def miro(method, prefix)
|
26
|
-
Miro.options[:color_count] = COUNT
|
27
|
-
Miro.options[:method] = method
|
28
|
-
|
29
|
-
colors = Miro::DominantColors.new(IMAGE)
|
30
|
-
replace("miro-#{prefix}", colors.to_hex)
|
31
|
-
end
|
32
|
-
|
33
|
-
def colorscore(prefix)
|
34
|
-
histogram = Colorscore::Histogram.new(IMAGE, COUNT)
|
35
|
-
replace("colorscore-#{prefix}", histogram.colors.map(&:html))
|
36
|
-
end
|
37
|
-
|
38
|
-
def camalian(quant, prefix)
|
39
|
-
image = Camalian::load(IMAGE)
|
40
|
-
colors = image.prominent_colors(COUNT, quantization: quant)
|
41
|
-
|
42
|
-
replace("camalian-#{prefix}", colors.map(&:to_hex))
|
43
|
-
end
|
44
|
-
|
45
|
-
def colordom(method, prefix)
|
46
|
-
colors = Colordom.send(method, IMAGE, COUNT)
|
47
|
-
replace("colordom-#{prefix}", colors.map(&:to_hex))
|
48
|
-
end
|
49
|
-
|
50
|
-
colordom(:histogram, 'hst')
|
51
|
-
colordom(:mediancut, 'mcq')
|
52
|
-
colordom(:kmeans, 'kms')
|
53
|
-
|
54
|
-
camalian(Camalian::QUANTIZATION_HISTOGRAM, 'hst')
|
55
|
-
camalian(Camalian::QUANTIZATION_MEDIAN_CUT, 'mcq')
|
56
|
-
camalian(Camalian::QUANTIZATION_K_MEANS, 'kms')
|
57
|
-
|
58
|
-
colorscore('hst')
|
59
|
-
|
60
|
-
miro('histogram', 'hst')
|
61
|
-
miro('pixel_group', 'pxg')
|
62
|
-
|
63
|
-
tempfile = Tempfile.create(['colordom-compare', '.svg'])
|
64
|
-
|
65
|
-
tempfile.write(TEMPL)
|
66
|
-
tempfile.close
|
67
|
-
|
68
|
-
system("xdg-open #{tempfile.path}")
|