'smooth_save' by robotp


Report abuse

Created on January 22, 2016 06:22 | Updated over 3 years ago

Link: https://spectralworkbench.org/macro/warren/smooth_save

smooth_save

// based on http://spectralworkbench.org/macro/warren/smooth_nosave

setup: function() {
  // code to run on startup

  $W.dialog('Smooth your data',
         'You can sample more than one row of your source image and average these rows to "smooth" your data. This can remove noise and make comparison easier. </p><p>The defaults are to average in the 10 rows just below your chosen cross-section.</p>',
         [["Cancel","$('.modal').hide()"],
          ["Smooth","$W.macros['smooth_save']()"]]
  )


  $W.macros['smooth_save'] = function() {

    // construct a canvas to store the image on while we get the data
    var rows = 10
    var orig_img = $('#image')[0]
    $('body').append("<canvas id='tmp_canvas'></canvas>")
    var img = new Image()
    img.src = orig_img.src
    var canvas = $('#tmp_canvas')[0]
    canvas.width = img.width
    canvas.height = img.height
    var ctx = canvas.getContext("2d")
    ctx.drawImage(img,0,0)

    var pixels = ctx.getImageData(0,$W.sample_row,canvas.width,rows).data

    // now, overwrite existing pixel rows in $W.spectrum
    $.each($W.spectrum['lines'],function(index,line) {

        // clear out existing data
        line['r'] = 0
        line['g'] = 0
        line['b'] = 0

        // for each row of data, add new data
        for (var i=0;i<rows;i++) {
            line['r'] += pixels[i*canvas.width*4+index*4]
            line['g'] += pixels[i*canvas.width*4+index*4+1]
            line['b'] += pixels[i*canvas.width*4+index*4+2]
        }

        // divide to get average per channel
        line['r'] = line['r']/rows
        line['g'] = line['g']/rows
        line['b'] = line['b']/rows

        // average colors to get overall
        line['average'] = (line['r'] + line['g'] + line['b'])/3

    })

    // graph smoothed data:
    var graph_data = []
    $.each($W.spectrum.lines,function(index,line) {
        if (line.wavelength == null) {
            line.wavelength = index
        }
        graph_data.push([line['wavelength'],line['average']/2.55])
    })

    $W.data.push({label: "Smoothed", data: graph_data})
    flotoptions.colors.push("#ff0000")
    $W.plot = $.plot($("#graph"),$W.data,flotoptions);

    $('.modal').hide()

  //}

  // we might prompt to save rather than do it automatically? Split up the method if so:

  //$W.macros['smooth_save_confirm']

    // upload and save

    var postable_data = $W.spectrum
    // we have to replace wavelengths with "null" if it's not calibrated
    if (!$W.calibrated) {
      $.each(postable_data.lines,function(i,line){
	    postable_data.lines[i]['wavelength'] = null
      })
    }
    postable_data = JSON.stringify(postable_data)

    $.ajax({
      url: '/spectrums/save/'+$W.spectrum_id,
      type: 'POST',
      data: {
        data: postable_data,
        tags: 'smoothed:'+$W.sample_row+'+'+rows,
        authenticity_token: $W.form_authenticity_token
      },
      success: function(res) {
        if (res == "true") {
           // display notice and the new tags
           $('#alerts').append('<div class="alert alert-success"><button type="button" class="close" data-dismiss="alert">×</button> Smoothed by '+rows+' pixels below sample row, and saved.</div>')
           // remove old "smoothed:" tags? do this in JS - server shouldn't have to care. We'll need a way to access tagnames and IDs in JS
        } else {
           alert(res)
        }
      }, 
      failure: function(res) {
	      alert("There was an error.")
      }
    })
  }

},
 
draw: function() {
  // code to run every frame
 
}