@@ -7,94 +7,22 @@ function findSeams(data, width, height, removeCount, onRemoveSeam) {
77 let energy = calcEnergy ( data , width , height ) ;
88 let workingData = data . slice ( ) ;
99 for ( let i = 0 ; i < removeCount ; i ++ ) {
10- // populate the first row in energySum
11- for ( let j = 0 ; j < energy . length ; j ++ ) {
12- energySum [ j ] = energy [ j ] ;
13- }
14- // populate the rest of the rows
15- for ( let y = 1 ; y < height ; y ++ ) {
16- for ( let x = 0 ; x < width ; x ++ ) {
17- const left = energySum [ ( y - 1 ) * width + Math . max ( x - 1 , 0 ) ] ;
18- const mid = energySum [ ( y - 1 ) * width + x ] ;
19- const right = energySum [ ( y - 1 ) * width + Math . min ( x + 1 , width - 1 ) ] ;
20- energySum [ y * width + x ] = energy [ y * width + x ] + Math . min ( left , mid , right ) ;
21- }
22- }
23- // find the min on the last row
24- let min = Infinity ;
25- let minx = 0 ;
26- for ( let x = 0 ; x < width ; x ++ ) {
27- if ( energySum [ ( height - 1 ) * width + x ] < min ) {
28- min = energySum [ ( height - 1 ) * width + x ] ;
29- minx = x ;
30- }
31- }
32- remove [ ( height - 1 ) ] = minx ;
33- // walk from the bottom up picking the min each time
34- for ( let y = height - 1 ; y >= 1 ; y -- ) {
35- const leftx = Math . max ( minx - 1 , 0 ) ;
36- const left = energySum [ ( y - 1 ) * width + leftx ] ;
37- const mid = energySum [ ( y - 1 ) * width + minx ] ;
38- const rightx = Math . min ( minx + 1 , width - 1 ) ;
39- const right = energySum [ ( y - 1 ) * width + rightx ] ;
40- if ( left < mid && left < right ) {
41- minx = leftx ;
42- }
43- else if ( right < mid && right < left ) {
44- minx = rightx ;
45- }
46- remove [ ( y - 1 ) ] = minx ;
47- }
10+ calcEnergySum ( energySum , energy , width , height ) ;
11+ findMinSeam ( remove , energySum , width , height ) ;
4812 workingData = removeSeam ( workingData , width , height , remove ) ;
4913 energy = recalcEnergy ( workingData , width - 1 , height , energy , remove ) ;
5014 width -- ;
5115 if ( onRemoveSeam ) {
5216 onRemoveSeam ( workingData , width ) ;
5317 }
5418 }
19+ workingData = workingData . slice ( 0 , width * height * 4 ) ;
5520 return workingData ;
5621}
5722exports . findSeams = findSeams ;
58- // debug functions
59- // replace the return of findSeams to return energy or energySum instead
60- function dbgEnergy ( energy ) {
61- const newData = new Uint8ClampedArray ( energy . length * 4 ) ;
62- const buf32 = new Uint32Array ( newData . buffer ) ;
63- for ( let i = 0 ; i < energy . length ; i ++ ) {
64- const nrg = energy [ i ] ;
65- buf32 [ i ] =
66- ( 0xff << 24 ) |
67- ( nrg << 16 ) |
68- ( nrg << 8 ) |
69- nrg ;
70- }
71- return newData ;
72- }
73- function dbgEnergySum ( energySum ) {
74- const newData = new Uint8ClampedArray ( energySum . length * 4 ) ;
75- const buf32 = new Uint32Array ( newData . buffer ) ;
76- let nrgMax = - Infinity ;
77- for ( let i = 0 ; i < energySum . length ; i ++ ) {
78- if ( energySum [ i ] > nrgMax ) {
79- nrgMax = energySum [ i ] ;
80- }
81- }
82- for ( let i = 0 ; i < energySum . length ; i ++ ) {
83- const nrg = ( energySum [ i ] / nrgMax ) * 255 ;
84- buf32 [ i ] =
85- ( 0xff << 24 ) |
86- ( nrg << 16 ) |
87- ( nrg << 8 ) |
88- nrg ;
89- }
90- return newData ;
91- }
9223// remove seams in remove from data, returning a new array.
93- // TODO mutate data instead of allocating a new array
9424function removeSeam ( data , width , height , remove ) {
9525 const data32 = new Uint32Array ( data . buffer ) ;
96- const newData = new Uint8ClampedArray ( ( width - 1 ) * height * 4 ) ;
97- const buf32 = new Uint32Array ( newData . buffer ) ;
9826 let offset = 0 ;
9927 for ( let y = 0 ; y < height ; y ++ ) {
10028 let removex = remove [ y ] ;
@@ -103,12 +31,12 @@ function removeSeam(data, width, height, remove) {
10331 // pixels been removed, skip over it
10432 offset ++ ;
10533 }
106- if ( x < width ) {
107- buf32 [ y * ( width - 1 ) + x ] = data32 [ y * ( width - 1 ) + x + offset ] ;
34+ if ( x < width && offset > 0 ) {
35+ data32 [ y * ( width - 1 ) + x ] = data32 [ y * ( width - 1 ) + x + offset ] ;
10836 }
10937 }
11038 }
111- return newData ;
39+ return data ;
11240}
11341function diff ( pixel1 , pixel2 ) {
11442 const r1 = pixel1 & 0xff ;
@@ -189,3 +117,81 @@ function recalcEnergy(data, width, height, energy, removed) {
189117 }
190118 return energy ;
191119}
120+ function calcEnergySum ( energySum , energy , width , height ) {
121+ // populate the first row in energySum
122+ for ( let j = 0 ; j < energy . length ; j ++ ) {
123+ energySum [ j ] = energy [ j ] ;
124+ }
125+ // populate the rest of the rows
126+ for ( let y = 1 ; y < height ; y ++ ) {
127+ // const removex = remove[y];
128+ // for (let x = Math.max(removex - y, 0); x < Math.min(removex + y, width); x++) {
129+ for ( let x = 0 ; x < width ; x ++ ) {
130+ const left = energySum [ ( y - 1 ) * width + Math . max ( x - 1 , 0 ) ] ;
131+ const mid = energySum [ ( y - 1 ) * width + x ] ;
132+ const right = energySum [ ( y - 1 ) * width + Math . min ( x + 1 , width - 1 ) ] ;
133+ energySum [ y * width + x ] = energy [ y * width + x ] + Math . min ( left , mid , right ) ;
134+ }
135+ }
136+ }
137+ function findMinSeam ( remove , energySum , width , height ) {
138+ // find the min on the last row
139+ let min = Infinity ;
140+ let minx = 0 ;
141+ for ( let x = 0 ; x < width ; x ++ ) {
142+ if ( energySum [ ( height - 1 ) * width + x ] < min ) {
143+ min = energySum [ ( height - 1 ) * width + x ] ;
144+ minx = x ;
145+ }
146+ }
147+ remove [ ( height - 1 ) ] = minx ;
148+ // walk from the bottom up picking the min each time
149+ for ( let y = height - 1 ; y >= 1 ; y -- ) {
150+ const leftx = Math . max ( minx - 1 , 0 ) ;
151+ const left = energySum [ ( y - 1 ) * width + leftx ] ;
152+ const mid = energySum [ ( y - 1 ) * width + minx ] ;
153+ const rightx = Math . min ( minx + 1 , width - 1 ) ;
154+ const right = energySum [ ( y - 1 ) * width + rightx ] ;
155+ if ( left < mid && left < right ) {
156+ minx = leftx ;
157+ }
158+ else if ( right < mid && right < left ) {
159+ minx = rightx ;
160+ }
161+ remove [ ( y - 1 ) ] = minx ;
162+ }
163+ }
164+ // debug functions
165+ // replace the return of findSeams to return energy or energySum instead
166+ function dbgEnergy ( energy ) {
167+ const newData = new Uint8ClampedArray ( energy . length * 4 ) ;
168+ const buf32 = new Uint32Array ( newData . buffer ) ;
169+ for ( let i = 0 ; i < energy . length ; i ++ ) {
170+ const nrg = energy [ i ] ;
171+ buf32 [ i ] =
172+ ( 0xff << 24 ) |
173+ ( nrg << 16 ) |
174+ ( nrg << 8 ) |
175+ nrg ;
176+ }
177+ return newData ;
178+ }
179+ function dbgEnergySum ( energySum ) {
180+ const newData = new Uint8ClampedArray ( energySum . length * 4 ) ;
181+ const buf32 = new Uint32Array ( newData . buffer ) ;
182+ let nrgMax = - Infinity ;
183+ for ( let i = 0 ; i < energySum . length ; i ++ ) {
184+ if ( energySum [ i ] > nrgMax ) {
185+ nrgMax = energySum [ i ] ;
186+ }
187+ }
188+ for ( let i = 0 ; i < energySum . length ; i ++ ) {
189+ const nrg = ( energySum [ i ] / nrgMax ) * 255 ;
190+ buf32 [ i ] =
191+ ( 0xff << 24 ) |
192+ ( nrg << 16 ) |
193+ ( nrg << 8 ) |
194+ nrg ;
195+ }
196+ return newData ;
197+ }
0 commit comments