Skip to content

Commit 01d718a

Browse files
committed
refactoring to have settings
1 parent 296d1e9 commit 01d718a

File tree

4 files changed

+71
-70
lines changed

4 files changed

+71
-70
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.9'`
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.9'
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: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,107 +26,110 @@ 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 self.configure(settings)
45+
@percent = settings[:percent] || DEFAULT_PERCENT_OF_DOTS
46+
@matrix = settings[:matrix] || DEFAULT_MATRIX_RANGE
47+
@with_not_detected_as_white = settings[:with_not_detected_as_white] || true
48+
@with_debug = settings[:with_debug] || false
49+
@with_debug_file = settings[:with_debug_file] || false
50+
@debug_file_path = settings[:debug_file_path] || DEFAULT_DEBUG_FILE_PATH
51+
end
3752

3853
def self.color(hex)
3954
@r, @g, @b = hex.match(/^#(..)(..)(..)$/).captures.map(&:hex)
4055
@colorset = MAXIMUM_COLOR_DEPTH
4156
dark?
4257
end
4358

44-
def self.magick_pixel(pix, x = nil, y = nil, set_not_detected_light = true)
59+
def self.magick_pixel(pix, x = nil, y = nil)
4560
@r = pix.red.to_f
4661
@g = pix.green.to_f
4762
@b = pix.blue.to_f
4863
@colorset = MAX_COLOR_VALUE
49-
dark?(x, y, set_not_detected_light)
64+
dark?(x, y)
5065
end
5166

52-
def self.magick_pixel_from_blob(x, y, blob, _set_not_detected_light = true)
67+
def self.magick_pixel_from_blob(x, y, blob)
5368
image = Magick::Image.read(blob).first
5469
pix = image.pixel_color(x, y)
5570
magick_pixel(pix, x, y)
5671
end
5772

5873
# (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
74+
def self.magick_area_from_blob(x, y, blob, height, width)
6375
image = Magick::Image.read(blob).first
6476
dark = false
6577
dots = []
66-
range.each do |xx|
67-
range.each do |yy|
78+
@matrix.each do |xx|
79+
@matrix.each do |yy|
6880
dots << { x: (x + (width * xx / 10)).to_i, y: (y + (height * yy / 10)).to_i }
6981
end
7082
end
7183

7284
points = 0
7385
if @with_debug_file
74-
oldx = false
75-
oldy = false
86+
old_x = false
87+
old_y = false
7688
end
77-
p '====================================================================' if @with_debug
89+
p '==================================================================================' if @with_debug
7890
dots.each do |dot|
7991
x = dot[:x].to_i
8092
y = dot[:y].to_i
8193
pix = image.pixel_color(x, y)
82-
l = magick_pixel(pix, x, y, set_not_detected_light)
94+
l = magick_pixel(pix, x, y)
8395
points += 1 if l
8496
next unless @with_debug_file
8597

86-
draw_debug_files(image, x, y, oldx, oldy)
87-
oldy = y
88-
oldx = x
98+
draw_debug_files(image, x, y, old_x, old_y)
99+
old_y = y
100+
old_x = x
89101
end
90-
dark = true if points >= (dots.length / 100) * percent
102+
dark = true if points >= (dots.length / 100) * @percent
91103
if @with_debug
92104
p '=================================================================================='
93105
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"
106+
p "Is \"invert to white not detectd pixels\" option enabled?:#{@with_not_detected_as_white}"
107+
p "Signature will be inverted if #{@percent}% of dots will be dark"
96108
p "Is inverted?: #{dark}"
97109
p "have a look on #{@debug_file_path} file to see your tested area of a blob"
98110
p '=================================================================================='
99111
end
100112
dark
101113
end
102114

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
115+
def self.draw_debug_files(image, x, y, old_x, old_y)
116+
return unless old_x && old_y
113117

114118
gc = Magick::Draw.new
115-
gc.line(x, y, oldx, oldy)
119+
gc.line(x, y, old_x, old_y)
116120
gc.stroke('black')
117121
gc.draw(image)
118122
image.write(@debug_file_path)
119123
end
120124

121125
# 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)
126+
def self.dark?(x = nil, y = nil)
123127
dark = false
124128
inverted = false
125129
pixel = [@r.to_f, @g.to_f, @b.to_f]
126130
return true if pixel == [0.00, 0.00, 0.00] # hardcoded exception
127131

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
132+
if @with_not_detected_as_white && pixel[0] == 0.0 && pixel[1] == 0.0 && pixel[2] == 0.0
130133
pixel = [MAXIMUM_COLOR_DEPTH, MAXIMUM_COLOR_DEPTH, MAXIMUM_COLOR_DEPTH]
131134
inverted = true
132135
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)