Module ChunkyPNG::Canvas::Resampling
In: lib/chunky_png/canvas/resampling.rb

The ChunkyPNG::Canvas::Resampling module defines methods to perform image resampling to a {ChunkyPNG::Canvas}.

Currently, only the nearest neighbor algorithm is implemented. Bilinear and cubic algorithms may be added later on.

@see ChunkyPNG::Canvas

Methods

Public Instance methods

resample(new_width, new_height)

[Source]

     # File lib/chunky_png/canvas/resampling.rb, line 139
139:       def resample_bilinear(new_width, new_height)
140:         dup.resample_bilinear!(new_width, new_height)
141:       end

Resamples the canvas with bilinear interpolation. @param [Integer] new_width The width of the resampled canvas. @param [Integer] new_height The height of the resampled canvas. @return [ChunkyPNG::Canvas] A new canvas instance with the resampled pixels.

[Source]

     # File lib/chunky_png/canvas/resampling.rb, line 103
103:       def resample_bilinear!(new_width, new_height)
104:         index_x, interp_x = steps_residues(width, new_width)
105:         index_y, interp_y = steps_residues(height, new_height)
106: 
107:         pixels = Array(size=new_width*new_height)
108:         i = 0
109:         for y in 1..new_height
110:           # Clamp the indicies to the edges of the image
111:           y1 = [index_y[y-1], 0].max
112:           y2 = [index_y[y-1] + 1, height - 1].min
113:           y_residue = interp_y[y-1]
114: 
115:           for x in 1..new_width
116:             # Clamp the indicies to the edges of the image
117:             x1 = [index_x[x-1], 0].max
118:             x2 = [index_x[x-1] + 1, width - 1].min
119:             x_residue = interp_x[x-1]
120: 
121:             pixel_11 = get_pixel(x1, y1)
122:             pixel_21 = get_pixel(x2, y1)
123:             pixel_12 = get_pixel(x1, y2)
124:             pixel_22 = get_pixel(x2, y2)
125: 
126:             # Interpolate by Row
127:             pixel_top = ChunkyPNG::Color.interpolate_quick(pixel_21, pixel_11, x_residue)
128:             pixel_bot = ChunkyPNG::Color.interpolate_quick(pixel_22, pixel_12, x_residue)
129: 
130:             # Interpolate by Column
131: 
132:             pixels[i] = ChunkyPNG::Color.interpolate_quick(pixel_bot, pixel_top, y_residue)
133:             i += 1
134:           end
135:         end
136:         replace_canvas!(new_width.to_i, new_height.to_i, pixels)
137:       end

[Source]

    # File lib/chunky_png/canvas/resampling.rb, line 95
95:       def resample_nearest_neighbor(new_width, new_height)
96:         dup.resample_nearest_neighbor!(new_width, new_height)
97:       end

Resamples the canvas using nearest neighbor interpolation. @param [Integer] new_width The width of the resampled canvas. @param [Integer] new_height The height of the resampled canvas. @return [ChunkyPNG::Canvas] A new canvas instance with the resampled pixels.

[Source]

    # File lib/chunky_png/canvas/resampling.rb, line 78
78:       def resample_nearest_neighbor!(new_width, new_height)
79:         steps_x = steps(width, new_width)
80:         steps_y = steps(height, new_height)
81: 
82: 
83:         pixels = Array(size=new_width*new_height)
84:         i = 0
85:         for y in steps_y
86:           for x in steps_x
87:             pixels[i] = get_pixel(x, y)
88:             i += 1
89:           end
90:         end
91:         
92:         replace_canvas!(new_width.to_i, new_height.to_i, pixels)
93:       end
resize(new_width, new_height)

Alias for resample

Integer Interpolation between two values

Used for generating indicies for interpolation (eg, nearest neighbour).

@param [Integer] width The width of the source @param [Integer] new_width The width of the destination @return [Array<Integer>] An Array of Integer indicies

[Source]

    # File lib/chunky_png/canvas/resampling.rb, line 24
24:       def steps(width, new_width)
25:         indicies, residues = steps_residues(width, new_width)
26:         
27:         for i in 1..new_width
28:           indicies[i-1] = (indicies[i-1] + (residues[i-1] + 127)/255)
29:         end
30:         return indicies
31:       end

Fractional Interpolation between two values

Used for generating values for interpolation (eg, bilinear). Produces both the indices and the interpolation factors (residues).

@param [Integer] width The width of the source @param [Integer] new_width The width of the destination @return [Array<Integer>, Array<Integer>] Two arrays of indicies and residues

[Source]

    # File lib/chunky_png/canvas/resampling.rb, line 41
41:       def steps_residues(width, new_width)
42:         indicies = Array.new(size=new_width, obj=nil)
43:         residues = Array.new(size=new_width, obj=nil)
44:         
45:         # This works by accumulating the fractional error and
46:         # overflowing when necessary.
47: 
48:         # We use mixed number arithmetic with a denominator of
49:         # 2 * new_width
50:         base_step = width / new_width
51:         err_step = (width % new_width) << 1
52:         denominator = (new_width) << 1
53:                 
54:         # Initial pixel
55:         index = (width - new_width) / denominator
56:         err = (width - new_width) % denominator
57: 
58:         for i in 1..new_width
59:           indicies[i-1] = index
60:           residues[i-1] = (255.0 * err.to_f / denominator.to_f).round
61: 
62:           index += base_step
63:           err += err_step
64:           if err >= denominator
65:             index += 1
66:             err -= denominator
67:           end
68:         end
69: 
70:         return indicies, residues
71:       end

[Validate]