Class: Diffux::SnapshotComparisonImage::Base

Inherits:
Object
  • Object
show all
Includes:
ChunkyPNG::Color
Defined in:
lib/diffux_core/snapshot_comparison_image/base.rb

Overview

This model represents a “comparison image”. Basically it’s just a wrapper around a ChunkyPNG image with some nice methods to make life easier in the world of diffs.

This model is never persisted.

Direct Known Subclasses

After, Before, Gutter, Overlayed

Constant Summary collapse

BASE_OPACITY =
0.1
BASE_ALPHA =
(255 * BASE_OPACITY).round
BASE_DIFF_ALPHA =
BASE_ALPHA * 2
MAGENTA =
ChunkyPNG::Color.from_hex '#b33682'
RED =
ChunkyPNG::Color.from_hex '#dc322f'
GREEN =
ChunkyPNG::Color.from_hex '#859900'

Instance Method Summary collapse

Constructor Details

#initialize(offset, canvas) ⇒ Base

Returns a new instance of Base.

Parameters:

  • offset (Integer)

    the x-offset that this comparison image should use when rendering on the canvas image.

  • canvas (ChunkyPNG::Image)

    The canvas image to render pixels on.



23
24
25
26
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 23

def initialize(offset, canvas)
  @offset = offset
  @canvas = canvas
end

Instance Method Details

#diff_alpha(diff_score) ⇒ Integer

Returns a number between 0 and 255 that represents the alpha channel of of the difference.

Parameters:

  • diff_score (Float)

Returns:

  • (Integer)

    a number between 0 and 255 that represents the alpha channel of of the difference



92
93
94
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 92

def diff_alpha(diff_score)
  (BASE_DIFF_ALPHA + ((255 - BASE_DIFF_ALPHA) * diff_score)).round
end

#pixel_diff_score(pixel_after, pixel_before) ⇒ Float

Compute a score that represents the difference between 2 pixels

This method simply takes the Euclidean distance between the RGBA channels of 2 colors over the maximum possible Euclidean distance. This gives us a percentage of how different the two colors are.

Although it would be more perceptually accurate to calculate a proper Delta E in Lab colorspace, we probably don’t need perceptual accuracy for this application, and it is nice to avoid the overhead of converting RGBA to Lab.

Parameters:

  • pixel_after (Integer)
  • pixel_before (Integer)

Returns:

  • (Float)

    number between 0 and 1 where 1 is completely different and 0 is no difference



84
85
86
87
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 84

def pixel_diff_score(pixel_after, pixel_before)
  ChunkyPNG::Color::euclidean_distance_rgba(pixel_after, pixel_before) /
    ChunkyPNG::Color::MAX_EUCLIDEAN_DISTANCE_RGBA
end

#render_added_row(y, row) ⇒ Object

Parameters:

  • y (Integer)
  • row (Diff::LCS:ContextChange)


59
60
61
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 59

def render_added_row(y, row)
  # no default implementation
end

#render_changed_row(y, row) ⇒ Object

Parameters:

  • y (Integer)
  • row (Diff::LCS:ContextChange)


53
54
55
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 53

def render_changed_row(y, row)
  # no default implementation
end

#render_deleted_row(y, row) ⇒ Object

Parameters:

  • y (Integer)
  • row (Diff::LCS:ContextChange)


65
66
67
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 65

def render_deleted_row(y, row)
  # no default implementation
end

#render_pixel(x, y, pixel) ⇒ Object

Renders a pixel on the specified x and y position. Uses the offset that the comparison image has been configured with.

Parameters:

  • x (Integer)
  • y (Integer)
  • pixel (Integer)


102
103
104
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 102

def render_pixel(x, y, pixel)
  @canvas.set_pixel(x + @offset, y, pixel)
end

#render_row(y, row) ⇒ Object

Parameters:

  • y (Integer)
  • row (Diff::LCS:ContextChange)


30
31
32
33
34
35
36
37
38
39
40
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 30

def render_row(y, row)
  if row.unchanged?
    render_unchanged_row(y, row)
  elsif row.deleting?
    render_deleted_row(y, row)
  elsif row.adding?
    render_added_row(y, row)
  else # changing?
    render_changed_row(y, row)
  end
end

#render_unchanged_row(y, row) ⇒ Object

Parameters:

  • y (Integer)
  • row (Diff::LCS:ContextChange)


44
45
46
47
48
49
# File 'lib/diffux_core/snapshot_comparison_image/base.rb', line 44

def render_unchanged_row(y, row)
  row.new_element.each_with_index do |pixel, x|
    # Render the unchanged pixel as-is
    render_pixel(x, y, pixel)
  end
end