Skip to content

Commit 7eccc6f

Browse files
committed
refactoring to have settings and initialize
1 parent 296d1e9 commit 7eccc6f

File tree

4 files changed

+76
-71
lines changed

4 files changed

+76
-71
lines changed

README.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# is_dark Ruby Gem
22
Ruby Gem to detect a dark color over an area from a blob of a file or by a color hex code based on [luminance w3 standarts]( https://www.w3.org/TR/WCAG20/#relativeluminancedef "luminance w3 standarts")
33

4-
https://github.com/user-attachments/assets/b5c46ae5-b608-4588-a497-b3bd3eb690ef
4+
https://github.com/user-attachments/assets/430cd789-1b5d-42a0-ae6e-c8b5f1da694b
55

66
#### Can detect:
77
* is a hex color dark
@@ -14,7 +14,7 @@ An example practical aspect: it can be useful to understand will a black colored
1414
#### How to Install:
1515

1616
Gemfile:
17-
`gem 'is_dark', '~> 0.1.7'`
17+
`gem 'is_dark', '~> 0.1.8'`
1818

1919
Install:
2020
`gem install is_dark`
@@ -35,19 +35,21 @@ Install:
3535
5. is Imagick area from a blob dark (by coordinates of a dot + width and height from the dot):
3636
`IsDark.magick_area_from_blob(x, y, blob, height, width)` #standart default settings
3737

38-
#### More examples:
39-
It also has kind of a development mode, when you can generate a debug outputs of all the generated dots based on provided coordinates. It can draw a test area over the file if you want, so you always can be sure, that you have valid coordinates on your tests.
40-
- `IsDark.set_debug_data(true, false)` #with debug info outputs in logs
41-
42-
- `IsDark.set_debug_data(true, '/var/www/project/is_dark_debug_output.pdf')` #with a generated debug pdf file (has displayed area of the analytics). You can use other file formats for the info (jpg, png, gif)
43-
44-
- `IsDark.magick_area_from_blob(x, y, blob, height, width)` #standart default settings
45-
46-
- ` IsDark.magick_area_from_blob(x, y, blob, cf_height, cf_width, 60, (1..10))` #additional settings (percent of dark dots amount to mark an area as a dark, range of matrix to build dots 1..10 - means 10x10; 0..10 - will have 121 dots for the analytics)
47-
48-
Sometimes Imagick can't detect a pixel or it has no color, so it detects it as (RGB: 0,0,0), the gem has an option to consider pixels like this as "white", but if you need to disable this option add true or false at the end of the method:
49-
50-
- ` IsDark.magick_area_from_blob(x, y, blob, cf_height, cf_width, 60, (1..10), false)` #detection "as white" is disabled)
38+
#### Settings:
39+
It also has kind of a development mode, when you can generate a debug outputs of all the generated dots based on provided coordinates. It can draw a test area over the file if you want, so you always can be sure, that you have valid coordinates on your tests. You can also set some other values and calibrate results as you need.
40+
41+
```ruby
42+
IsDark.configure({
43+
percent: 70, #percent of dark dots under an area to mark all the area as dark
44+
matrix: (0..10), #range of dots to analyse. (0..10) means matrix 10x10 or 100 dots to analyse
45+
with_not_detected_as_white: true, # Sometimes Imagick can't detect a pixel or it has no color, so it detects it as (RGB: 0,0,0), the gem has an option to consider pixels like this as "white", but if you need to disable this option add true or false
46+
with_debug: true, #show debug output
47+
with_debug_file: true, #draw a tested area in a copy of your blob file
48+
debug_file_path: debug_file_path #path of the file with a drawn area
49+
})
50+
```
51+
You can use these settings and test it after with this command:
52+
`IsDark.magick_area_from_blob(x, y, blob, height, width)`, so it will show a debug info with a generated file
5153

5254
#### Unit Tests:
5355

is_dark.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Gem::Specification.new do |s|
44
s.name = 'is_dark'
5-
s.version = '0.1.7'
5+
s.version = '0.1.8'
66
s.summary = 'Detects a dark background under an area or by a color code'
77
s.description = 'Detects a dark color based on luminance W3 standarts ' \
88
"( https://www.w3.org/TR/WCAG20/#relativeluminancedef ). \n\n " \

lib/is_dark.rb

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,107 +26,114 @@ class IsDark
2626
NONLINEAR_TRANSFORM_DIVIDER = 1.055
2727
NONLINEAR_TRANSFORM_OFFSET = 0.055
2828
RED_LUMINANCE_COEFFICIENT = 0.2126
29+
DEFAULT_PERCENT_OF_DOTS = 80
30+
DEFAULT_MATRIX_RANGE = (0..10).freeze
31+
DEFAULT_DEBUG_FILE_PATH = '/tmp/is_dark_debug_file.pdf'
2932

3033
@r = 0
3134
@g = 0
3235
@b = 0
3336
@colorset = MAXIMUM_COLOR_DEPTH
37+
@percent = DEFAULT_PERCENT_OF_DOTS
38+
@matrix = DEFAULT_MATRIX_RANGE
39+
@with_not_detected_as_white = true
3440
@with_debug = false
3541
@with_debug_file = false
36-
@debug_file_path = '/tmp/is_dark_debug_file.pdf'
42+
@debug_file_path = DEFAULT_DEBUG_FILE_PATH
43+
44+
def initialize(settings)
45+
configure(settings) unless settings.nil?
46+
end
47+
48+
def self.configure(settings)
49+
@percent = settings[:percent] || DEFAULT_PERCENT_OF_DOTS
50+
@matrix = settings[:matrix] || DEFAULT_MATRIX_RANGE
51+
@with_not_detected_as_white = settings[:with_not_detected_as_white] || true
52+
@with_debug = settings[:with_debug] || false
53+
@with_debug_file = settings[:with_debug_file] || false
54+
@debug_file_path = settings[:debug_file_path] || DEFAULT_DEBUG_FILE_PATH
55+
end
3756

3857
def self.color(hex)
3958
@r, @g, @b = hex.match(/^#(..)(..)(..)$/).captures.map(&:hex)
4059
@colorset = MAXIMUM_COLOR_DEPTH
4160
dark?
4261
end
4362

44-
def self.magick_pixel(pix, x = nil, y = nil, set_not_detected_light = true)
63+
def self.magick_pixel(pix, x = nil, y = nil)
4564
@r = pix.red.to_f
4665
@g = pix.green.to_f
4766
@b = pix.blue.to_f
4867
@colorset = MAX_COLOR_VALUE
49-
dark?(x, y, set_not_detected_light)
68+
dark?(x, y)
5069
end
5170

52-
def self.magick_pixel_from_blob(x, y, blob, _set_not_detected_light = true)
71+
def self.magick_pixel_from_blob(x, y, blob)
5372
image = Magick::Image.read(blob).first
5473
pix = image.pixel_color(x, y)
5574
magick_pixel(pix, x, y)
5675
end
5776

5877
# (x, y) is the left corner of an element over a blob, height and width is the element's size
59-
def self.magick_area_from_blob(
60-
x, y, blob, height, width, percent = 80, range = (0..10), set_not_detected_light = true
61-
)
62-
@set_not_detected_light = set_not_detected_light
78+
def self.magick_area_from_blob(x, y, blob, height, width)
6379
image = Magick::Image.read(blob).first
6480
dark = false
6581
dots = []
66-
range.each do |xx|
67-
range.each do |yy|
82+
@matrix.each do |xx|
83+
@matrix.each do |yy|
6884
dots << { x: (x + (width * xx / 10)).to_i, y: (y + (height * yy / 10)).to_i }
6985
end
7086
end
7187

7288
points = 0
7389
if @with_debug_file
74-
oldx = false
75-
oldy = false
90+
old_x = false
91+
old_y = false
7692
end
77-
p '====================================================================' if @with_debug
93+
p '==================================================================================' if @with_debug
7894
dots.each do |dot|
7995
x = dot[:x].to_i
8096
y = dot[:y].to_i
8197
pix = image.pixel_color(x, y)
82-
l = magick_pixel(pix, x, y, set_not_detected_light)
98+
l = magick_pixel(pix, x, y)
8399
points += 1 if l
84100
next unless @with_debug_file
85101

86-
draw_debug_files(image, x, y, oldx, oldy)
87-
oldy = y
88-
oldx = x
102+
draw_debug_files(image, x, y, old_x, old_y)
103+
old_y = y
104+
old_x = x
89105
end
90-
dark = true if points >= (dots.length / 100) * percent
106+
dark = true if points >= (dots.length / 100) * @percent
91107
if @with_debug
92108
p '=================================================================================='
93109
p "Total Points: #{dots.length}, dark points amount:#{points}"
94-
p "Is \"invert to white not detectd pixels\" option enabled?:#{set_not_detected_light}"
95-
p "Signature will be inverted if #{percent}% of dots will be dark"
110+
p "Is \"invert to white not detectd pixels\" option enabled?:#{@with_not_detected_as_white}"
111+
p "Signature will be inverted if #{@percent}% of dots will be dark"
96112
p "Is inverted?: #{dark}"
97113
p "have a look on #{@debug_file_path} file to see your tested area of a blob"
98114
p '=================================================================================='
99115
end
100116
dark
101117
end
102118

103-
def self.set_debug_data(show_info = false, draw_file = false)
104-
@with_debug = show_info
105-
return unless draw_file != false
106-
107-
@with_debug_file = true
108-
@debug_file_path = draw_file
109-
end
110-
111-
def self.draw_debug_files(image, x, y, oldx, oldy)
112-
return unless oldx && oldy
119+
def self.draw_debug_files(image, x, y, old_x, old_y)
120+
return unless old_x && old_y
113121

114122
gc = Magick::Draw.new
115-
gc.line(x, y, oldx, oldy)
123+
gc.line(x, y, old_x, old_y)
116124
gc.stroke('black')
117125
gc.draw(image)
118126
image.write(@debug_file_path)
119127
end
120128

121129
# detects a dark color based on luminance W3 standarts ( https://www.w3.org/TR/WCAG20/#relativeluminancedef )
122-
def self.dark?(x = nil, y = nil, set_not_detected_light = true)
130+
def self.dark?(x = nil, y = nil)
123131
dark = false
124132
inverted = false
125133
pixel = [@r.to_f, @g.to_f, @b.to_f]
126134
return true if pixel == [0.00, 0.00, 0.00] # hardcoded exception
127135

128-
# probably not detected pixel color by Imagick, will be considered as "white" if "set_not_detected_light = true"
129-
if set_not_detected_light && pixel[0] == 0.0 && pixel[1] == 0.0 && pixel[2] == 0.0
136+
if @with_not_detected_as_white && pixel[0] == 0.0 && pixel[1] == 0.0 && pixel[2] == 0.0
130137
pixel = [MAXIMUM_COLOR_DEPTH, MAXIMUM_COLOR_DEPTH, MAXIMUM_COLOR_DEPTH]
131138
inverted = true
132139
end
@@ -151,4 +158,4 @@ def self.dark?(x = nil, y = nil, set_not_detected_light = true)
151158
end
152159
dark
153160
end
154-
end
161+
end

spec/lib/is_dark_spec.rb

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,7 @@
8888
y = 120 # coordinate of a left corner of the area's rectangle Y
8989
cf_height = 64 # height of the area's rectangle
9090
cf_width = 128 # height of the area's rectangle
91-
percent = 70 # percent of detected dark pixels to invert
92-
matrix = (1..10) # matrix of dots. Range of matrix to build dots 1..10 - means 10x10
93-
# Sometimes Imagick can't detect a pixel or it has no color, so it detects it as (RGB: 0,0,0), the gem has an
94-
# option to consider pixels like this as "white", but if you need to disable this option add true or false.
95-
with_not_detected = false
96-
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width, percent, matrix,
97-
with_not_detected)).to eq(false)
91+
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width)).to eq(false)
9892
end
9993
end
10094

@@ -104,13 +98,7 @@
10498
y = 120 # coordinate of a left corner of the area's rectangle Y
10599
cf_height = 64 # height of the area's rectangle
106100
cf_width = 128 # height of the area's rectangle
107-
percent = 70 # percent of detected dark pixels to invert
108-
matrix = (1..10) # matrix of dots. Range of matrix to build dots 1..10 - means 10x10
109-
# Sometimes Imagick can't detect a pixel or it has no color, so it detects it as (RGB: 0,0,0), the gem has
110-
# an option to consider pixels like this as "white", but if you need to disable this option add true or false.
111-
with_not_detected = false
112-
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width, percent, matrix,
113-
with_not_detected)).to eq(false)
101+
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width)).to eq(false)
114102
end
115103
end
116104

@@ -120,14 +108,22 @@
120108
y = 120 # coordinate of a left corner of the area's rectangle Y
121109
cf_height = 64 # height of the area's rectangle
122110
cf_width = 128 # height of the area's rectangle
123-
percent = 70 # percent of detected dark pixels to invert
111+
percent = 70 # percent of detected dark pixels to mark as dark
124112
matrix = (1..10) # matrix of dots. Range of matrix to build dots 1..10 - means 10x10
125113
# Sometimes Imagick can't detect a pixel or it has no color, so it detects it as (RGB: 0,0,0), the gem has
126-
# an option to consider pixels like this as "white", but if you need to disable this option add true or false.
127-
with_not_detected = false
128-
IsDark.set_debug_data(true, './is_dark_debug_output.pdf')
129-
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width, percent, matrix,
130-
with_not_detected)).to eq(false)
114+
# an option to consider pixels like this as "white", but if you need to disable this option add true or false:
115+
not_detected = false
116+
# generated file with lines through dots of the matrix over a tested area:
117+
debug_file_path = './is_dark_debug_file.pdf'
118+
IsDark.configure({
119+
percent: percent,
120+
matrix: matrix,
121+
with_not_detected_as_white: not_detected,
122+
with_debug: true,
123+
with_debug_file: true,
124+
debug_file_path: debug_file_path
125+
})
126+
expect(IsDark.magick_area_from_blob(x, y, TEST_FILE_PATH, cf_height, cf_width)).to eq(false)
131127
end
132128
end
133129
end

0 commit comments

Comments
 (0)