Class: Capybara::Screenshot::Diff::Drivers::VipsDriver

Inherits:
BaseDriver
  • Object
show all
Defined in:
lib/capybara/screenshot/diff/drivers/vips_driver.rb

Defined Under Namespace

Classes: VipsUtil

Constant Summary collapse

MAX_FILENAME_LENGTH =
200

Constants inherited from BaseDriver

BaseDriver::PNG_EXTENSION

Instance Method Summary collapse

Methods inherited from BaseDriver

#height_for, #image_area_size, #inscribed?, #same_dimension?, #width_for

Instance Method Details

#add_black_box(memo, region) ⇒ Object



51
52
53
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 51

def add_black_box(memo, region)
  memo.draw_rect([0, 0, 0, 0], *region.to_top_left_corner_coordinates, fill: true)
end

#crop(region, i) ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 37

def crop(region, i)
  i.crop(*region.to_top_left_corner_coordinates)
rescue Vips::Error => e
  warn(
    "[capybara-screenshot-diff] Crop has been failed for " \
    "{ region: #{region.to_top_left_corner_coordinates.inspect}, image: #{dimension(i).join("x")} }"
  )
  raise e
end

#difference_level(diff_mask, old_img, _region = nil) ⇒ Object



55
56
57
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 55

def difference_level(diff_mask, old_img, _region = nil)
  VipsUtil.difference_area_size_by(diff_mask).to_f / image_area_size(old_img)
end

#dimension(image) ⇒ Object



89
90
91
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 89

def dimension(image)
  [width_for(image), height_for(image)]
end

#draw_rectangles(images, region, rgba, offset: 0) ⇒ Object



93
94
95
96
97
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 93

def draw_rectangles(images, region, rgba, offset: 0)
  images.map do |image|
    image.draw_rect(rgba, region.left - offset, region.top - offset, region.width + (offset * 2), region.height + (offset * 2))
  end
end

#filter_image_with_median(image, median_filter_window_size) ⇒ Object



47
48
49
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 47

def filter_image_with_median(image, median_filter_window_size)
  image.median(median_filter_window_size)
end

#find_difference_region(comparison) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 19

def find_difference_region(comparison)
  new_image, base_image, options = comparison.new_image, comparison.base_image, comparison.options

  diff_mask = VipsUtil.difference_mask(base_image, new_image, options[:color_distance_limit])
  region = VipsUtil.difference_region_by(diff_mask)
  region = nil if region && same_as?(region, base_image)

  result = Difference.new(region, {}, comparison)

  unless result.blank?
    meta = {}
    meta[:difference_level] = difference_level(diff_mask, base_image) if comparison.options[:tolerance]
    result.meta = meta
  end

  result
end

#from_file(filename) ⇒ Object



80
81
82
83
84
85
86
87
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 80

def from_file(filename)
  result = ::Vips::Image.new_from_file(filename.to_s)

  result = result.colourspace(:srgb) if result.bands < 3
  result = result.bandjoin(255) if result.bands == 3

  result
end

#load_images(old_file_name, new_file_name) ⇒ Object



76
77
78
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 76

def load_images(old_file_name, new_file_name)
  [from_file(old_file_name), from_file(new_file_name)]
end

#resize_image_to(image, new_width, new_height) ⇒ Object



72
73
74
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 72

def resize_image_to(image, new_width, new_height)
  image.resize(new_width.to_f / new_height)
end

#same_pixels?(comparison) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 99

def same_pixels?(comparison)
  (comparison.new_image == comparison.base_image).min == 255
end

#save_image_to(image, filename) ⇒ Object

Vips could not work with the same file. Per each process we require to create new file



62
63
64
65
66
67
68
69
70
# File 'lib/capybara/screenshot/diff/drivers/vips_driver.rb', line 62

def save_image_to(image, filename)
  # Dir::Tmpname will happily produce tempfile names that are too long for most unix filesystems,
  # which leads to "unix error: File name too long". Apply a limit to avoid this.
  limited_filename = filename.to_s[-MAX_FILENAME_LENGTH..] || filename.to_s
  ::Dir::Tmpname.create([limited_filename, PNG_EXTENSION]) do |tmp_image_filename|
    image.write_to_file(tmp_image_filename)
    FileUtils.mv(tmp_image_filename, filename)
  end
end