Module: Applitools::Utils::ImageUtils

Extended by:
ImageUtils
Included in:
ImageUtils
Defined in:
lib/applitools/utils/image_utils.rb

Instance Method Summary collapse

Instance Method Details

#base64_from_png_image(image) ⇒ String

Get the Base64 representation of the raw PNG bytes of an image.

Parameters:

  • image (ChunkyPNG::Canvas)

    The image object for which to get the PNG bytes.

Returns:

  • (String)

    the Base64 representation of the raw PNG bytes of an image.



39
40
41
# File 'lib/applitools/utils/image_utils.rb', line 39

def base64_from_png_image(image)
  Base64.encode64(bytes_from_png_image(image))
end

#bytes_from_png_image(image) ⇒ String

Get the raw PNG bytes of an image.

Parameters:

  • image (ChunkyPNG::Canvas)

    The image object for which to get the PNG bytes.

Returns:

  • (String)

    The PNG bytes of the image.



32
33
34
# File 'lib/applitools/utils/image_utils.rb', line 32

def bytes_from_png_image(image)
  image.to_blob(:fast_rgb)
end

#cut(image, crop_region) ⇒ Object

Cuts the image according to passed crop_region. The method returns new instance of the image without changing the source image.

Parameters:

  • image (ChunkyPNG::Canvas)

    The image to cut

  • crop_region (Applitools::Region)

    The region which represents cut bounds. The area outside crop_region will be removed from the image.



75
76
77
# File 'lib/applitools/utils/image_utils.rb', line 75

def cut(image, crop_region)
  cut! image.dup, crop_region
end

#cut!(image, crop_region) ⇒ Object

Cuts the image according to passed crop_region. The method mutates an image.

Parameters:

  • image (ChunkyPNG::Canvas)

    The image to cut

  • crop_region (Applitools::Region)

    The region which represents cut bounds. The area outside crop_region will be removed from the image.



66
67
68
# File 'lib/applitools/utils/image_utils.rb', line 66

def cut!(image, crop_region)
  image.crop! crop_region.left, crop_region.top, crop_region.width, crop_region.height
end

#png_image_from_base64(png_bytes) ⇒ ChunkyPNG::Canvas

Creates an image instance from a base64 representation of its PNG encoding.

Parameters:

  • png_bytes (String)

    The Base64 representation of a PNG image.

Returns:

  • (ChunkyPNG::Canvas)

    An image object.



25
26
27
# File 'lib/applitools/utils/image_utils.rb', line 25

def png_image_from_base64(png_bytes)
  png_image_from_bytes(Base64.decode64(png_bytes))
end

#png_image_from_bytes(png_bytes) ⇒ ChunkyPNG::Canvas

Creates an image object from the PNG bytes.

Parameters:

  • png_bytes (String)

    A binary string of the PNG bytes of the image.

Returns:

  • (ChunkyPNG::Canvas)

    An image object.



18
19
20
# File 'lib/applitools/utils/image_utils.rb', line 18

def png_image_from_bytes(png_bytes)
  ChunkyPNG::Image.from_blob(png_bytes)
end

#quadrant_rotate!(image, num_quadrants) ⇒ Object

Rotates a matrix 90 deg clockwise or counter clockwise (depending whether num_quadrants is positive or negative, respectively).

Parameters:

  • image (ChunkyPNG::Canvas)

    The image to rotate.

  • num_quadrants (Integer)

    The number of rotations to perform. Positive values are used for clockwise rotation and negative values are used for counter-clockwise rotation.



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/applitools/utils/image_utils.rb', line 48

def quadrant_rotate!(image, num_quadrants)
  num_quadrants %= QUADRANTS_COUNT
  case num_quadrants
  when 0
    image
  when 1
    image.rotate_right!
  when 2
    image.rotate_180!
  when 3
    image.rotate_left!
  end
end

#resize_image(image, new_width, new_height) ⇒ Object



116
117
118
# File 'lib/applitools/utils/image_utils.rb', line 116

def resize_image(image, new_width, new_height)
  resize_image!(image.dup, new_width, new_height)
end

#resize_image!(image, new_width, new_height) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/applitools/utils/image_utils.rb', line 98

def resize_image!(image, new_width, new_height)
  Applitools::ArgumentGuard.not_nil(new_width, 'new_width')
  Applitools::ArgumentGuard.not_nil(new_height, 'new_height')
  Applitools::ArgumentGuard.not_nil(image, 'image')
  Applitools::ArgumentGuard.is_a?(image, 'image', ::ChunkyPNG::Image)

  raise Applitools::EyesIllegalArgument.new "Invalid width: #{new_width}" if new_width <= 0
  raise Applitools::EyesIllegalArgument.new "Invalid height: #{new_height}" if new_height <= 0

  return image if image.width == new_width && image.height == new_height

  if new_width > image.width || new_height > image.height
    image.resample_bicubic!(new_width, new_height)
  else
    scale_image_incrementally!(image, new_width, new_height)
  end
end

#scale(image, scale_ratio) ⇒ Object



94
95
96
# File 'lib/applitools/utils/image_utils.rb', line 94

def scale(image, scale_ratio)
  scale!(image.dup, scale_ratio)
end

#scale!(image, scale_ratio) ⇒ Applitools::Screenshot

Scales image by given scale factor by modifying given image

Parameters:

  • image (Applitools::Screenshot)

    An image to scale. (The source image will be modified by invoking the method)

  • scale_ratio (Float)

    Scale factor.

Returns:



84
85
86
87
88
89
90
91
92
# File 'lib/applitools/utils/image_utils.rb', line 84

def scale!(image, scale_ratio)
  return image if scale_ratio == 1
  image_ratio = image.width.to_f / image.height.to_f
  scale_width = (image.width * scale_ratio).ceil
  scale_height = (scale_width / image_ratio).ceil
  buffered_image = image.image
  resize_image!(buffered_image, scale_width, scale_height)
  image.update!(buffered_image)
end

#scale_image_incrementally(image, new_width, new_height) ⇒ Object



144
145
146
# File 'lib/applitools/utils/image_utils.rb', line 144

def scale_image_incrementally(image, new_width, new_height)
  scale_image_incrementally!(image.dup, new_width, new_height)
end

#scale_image_incrementally!(image, new_width, new_height) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/applitools/utils/image_utils.rb', line 120

def scale_image_incrementally!(image, new_width, new_height)
  current_width = image.width
  current_height = image.height

  while current_width != new_width || current_height != new_height
    prev_current_width = current_width
    prev_current_height = current_height
    if current_width > new_width
      current_width -= (current_width / RESAMPLE_INCREMENTALLY_FRACTION)
      current_width = new_width if current_width < new_width
    end

    if current_height > new_height
      current_height -= (current_height / RESAMPLE_INCREMENTALLY_FRACTION)
      current_height = new_height if current_height < new_height
    end

    return image if prev_current_width == current_width && prev_current_height == current_height
    Applitools::EyesLogger.debug "Incremental dimensions: #{current_width} x #{current_height}"
    image.resample_bicubic!(current_width, current_height)
  end
  image
end