+
+
+
+
+
+
+
-
+
@@ -201,234 +223,248 @@
import svgChart from './components/svgChart';
export default {
- name: 'App',
- components: {
- imageChooser: ImageChooser,
- webcam: WebCam,
- svgChart: svgChart
- },
- data() {
- return {
- cropper: {},
- dataUrl: '',
- lines: [],
- inputType: "upload",
- settings: {
- frequency: 150,
- amplitude: 1,
- lineCount: 50,
- brightness: 0,
- contrast: 0,
- minBrightness: 0,
- maxBrightness: 255,
- spacing: 1,
- width: 500,
- height: 500
- },
- canvasData: null,
- webcam: {
- img: null,
- camera: null,
- deviceId: null,
- device: null,
- devices: [],
- streaming: false
- },
- };
- },
-
- watch: {
- 'webcam.camera': function(id) {
- this.webcam.deviceId = id;
+ name: 'App',
+ components: {
+ imageChooser: ImageChooser,
+ webcam: WebCam,
+ svgChart: svgChart
},
- 'webcam.devices': function() {
- // Once we have a list select the first one
- let first = this.webcam.devices[0];
- if (first) {
- this.webcam.camera = first.deviceId;
- this.webcam.deviceId = first.deviceId;
+ data() {
+ return {
+ cropper: {},
+ dataUrl: '',
+ lines: [],
+ inputType: "upload",
+ settings: {
+ black: false,
+ frequency: 150,
+ amplitude: 1,
+ lineCount: 50,
+ brightness: 0,
+ contrast: 0,
+ minBrightness: 0,
+ maxBrightness: 255,
+ spacing: 1,
+ width: 500,
+ height: 500
+ },
+ canvasData: null,
+ webcam: {
+ img: null,
+ camera: null,
+ deviceId: null,
+ device: null,
+ devices: [],
+ streaming: false
+ },
+ };
+ },
+
+ watch: {
+ 'webcam.camera': function(id) {
+ this.webcam.deviceId = id;
+ },
+ 'webcam.devices': function() {
+ // Once we have a list select the first one
+ let first = this.webcam.devices[0];
+ if (first) {
+ this.webcam.camera = first.deviceId;
+ this.webcam.deviceId = first.deviceId;
+ }
+ },
+ 'settings.frequency': function(){
+ this.processImage();
+ },
+ 'settings.spacing': function(){
+ this.processImage();
+ },
+ 'settings.lineCount': function(){
+ this.processImage();
+ },
+ 'settings.amplitude': function(){
+ this.processImage();
+ },
+ 'settings.minBrightness': function(){
+ this.processImage();
+ },
+ 'settings.maxBrightness': function(){
+ this.processImage();
+ },
+ 'settings.brightness': function(){
+ this.processImage();
+ },
+ 'settings.contrast': function(){
+ this.processImage();
+ },
+ 'settings.black': function(){
+ this.processImage();
+ },
+ 'canvasData': function(){
+ this.processImage();
}
},
- 'settings.frequency': function(){
- this.processImage();
+ computed: {
+ widthInCM(){
+ return Math.round(10*this.settings.width / 38)/10;
+ },
+ heightInCM(){
+ return Math.round(10*this.settings.height / 38)/10;
+ }
},
- 'settings.spacing': function(){
- this.processImage();
- },
- 'settings.lineCount': function(){
- this.processImage();
- },
- 'settings.amplitude': function(){
- this.processImage();
- },
- 'settings.minBrightess': function(){
- this.processImage();
- },
- 'settings.maxBrightness': function(){
- this.processImage();
- },
- 'settings.brightness': function(){
- this.processImage();
- },
- 'settings.contrast': function(){
- this.processImage();
- },
- 'canvasData': function(){
- this.processImage();
- }
- },
+ methods: {
+ downloadSVG(){
+ const svgDoctype = ''
+ + '';
- methods: {
- downloadSVG(){
- const svgDoctype = ''
- + '';
+ // serialize our SVG XML to a string.
+ const svgString = (new XMLSerializer()).serializeToString(this.$refs.svgResult.$el);
+ const blob = new Blob([svgDoctype + svgString], {type: 'image/svg+xml;charset=utf-8'});
- // serialize our SVG XML to a string.
- const svgString = (new XMLSerializer()).serializeToString(this.$refs.svgResult.$el);
- const blob = new Blob([svgDoctype + svgString], {type: 'image/svg+xml;charset=utf-8'});
+ /* This portion of script saves the file to local filesystem as a download */
+ const svgUrl = URL.createObjectURL(blob);
+ const downloadLink = document.createElement("a");
+ downloadLink.href = svgUrl;
+ downloadLink.download = "squiggleCam_" + Date.now() + ".svg";
+ document.body.appendChild(downloadLink);
+ downloadLink.click();
+ document.body.removeChild(downloadLink);
+ },
+ uploadCroppedImage() {
+ this.cropper.generateBlob((blob) => {
+ let canvas = document.createElement("canvas");
+ canvas.width = this.settings.width;
+ canvas.height = this.settings.height;
- /* This portion of script saves the file to local filesystem as a download */
- const svgUrl = URL.createObjectURL(blob);
- const downloadLink = document.createElement("a");
- downloadLink.href = svgUrl;
- downloadLink.download = "squiggleCam_" + Date.now() + ".svg";
- document.body.appendChild(downloadLink);
- downloadLink.click();
- document.body.removeChild(downloadLink);
- },
- uploadCroppedImage() {
- this.cropper.generateBlob((blob) => {
- let canvas = document.createElement("canvas");
- canvas.width = this.settings.width;
- canvas.height = this.settings.height;
+ const ctx = canvas.getContext('2d');
+ let img = new Image();
- const ctx = canvas.getContext('2d');
- let img = new Image();
+ img.onload = () => {
+ ctx.drawImage(img, 0, 0)
+ this.canvasData = ctx.getImageData(0, 0, this.settings.width, this.settings.height);
+ };
- img.onload = () => {
- ctx.drawImage(img, 0, 0)
- this.canvasData = ctx.getImageData(0, 0, this.settings.width, this.settings.height);
- };
-
- img.src = URL.createObjectURL(blob);
- }, 'image/jpeg', 1)
- },
- processImage() {
- this.$worker.run((data) => {
- // Gather all necessary data from the main thread
- let config = data.config;
+ img.src = URL.createObjectURL(blob);
+ }, 'image/jpeg', 1)
+ },
+ processImage() {
+ this.$worker.run((data) => {
+ // Gather all necessary data from the main thread
+ let config = data.config;
// context.getImageData(0, 0, config.WIDTH, config.HEIGHT);
- const imagePixels = data.image;
- const width = parseInt(config.width);
- const height = parseInt(config.height);
- const contrast = parseInt(config.contrast);
- const brightness = parseInt(config.brightness);
- const lineCount = parseInt(config.lineCount);
- const minBrightness = parseInt(config.minBrightness);
- const maxBrightness = parseInt(config.maxBrightness);
- const spacing = parseFloat(config.spacing);
+ const imagePixels = data.image;
+ const width = parseInt(config.width);
+ const height = parseInt(config.height);
+ const contrast = parseInt(config.contrast);
+ const brightness = parseInt(config.brightness);
+ const lineCount = parseInt(config.lineCount);
+ const minBrightness = parseInt(config.minBrightness);
+ const maxBrightness = parseInt(config.maxBrightness);
+ const spacing = parseFloat(config.spacing);
+ const black = config.black;
// Create some defaults for squiggle-point array
- let squiggleData = [];
- let r = 5;
- let a = 0;
- let b;
- let z;
- let currentLine = []; // create empty array for storing x,y coordinate pairs
- let currentVerticalPixelIndex = 0;
- let currentHorizontalPixelIndex = 0;
- let contrastFactor = (259 * (contrast + 255)) / (255 * (259 - contrast)); // This was established through experiments
- let horizontalLineSpacing = Math.floor(height / lineCount); // Number of pixels to advance in vertical direction
- //console.log(horizontalLineSpacing);
+ let squiggleData = [];
+ let r = 5;
+ let a = 0;
+ let b;
+ let z;
+ let currentLine = []; // create empty array for storing x,y coordinate pairs
+ let currentVerticalPixelIndex = 0;
+ let currentHorizontalPixelIndex = 0;
+ let contrastFactor = (259 * (contrast + 255)) / (255 * (259 - contrast)); // This was established through experiments
+ let horizontalLineSpacing = Math.floor(height / lineCount); // Number of pixels to advance in vertical direction
// Iterate line by line (top line to bottom line) in increments of horizontalLineSpacing
- //let tmpCounter = 0;
- for (let y = 0; y < height; y+= horizontalLineSpacing) {
- a = 0;
- currentLine = [];
- currentLine.push([0, y]); // Start the line
+ //let tmpCounter = 0;
+ for (let y = 0; y < height; y+= horizontalLineSpacing) {
+ a = 0;
+ currentLine = [];
+ currentLine.push([0, y]); // Start the line
- currentVerticalPixelIndex = y*width; // Because Image Pixel array is of length width * height,
- // starting pixel for each line will be this
+ currentVerticalPixelIndex = y*width; // Because Image Pixel array is of length width * height,
+ // starting pixel for each line will be this
- // Loop through pixels from left to right within the current line, advancing by increments of config.SPACING
- //console.log(config.spacing, width);
- for (let x = spacing; x < width; x += spacing ) {
+ // Loop through pixels from left to right within the current line, advancing by increments of config.SPACING
+ //console.log(config.spacing, width);
+ for (let x = spacing; x < width; x += spacing ) {
- currentHorizontalPixelIndex = Math.floor(x + currentVerticalPixelIndex); // Get array position of current pixel
+ currentHorizontalPixelIndex = Math.floor(x + currentVerticalPixelIndex); // Get array position of current pixel
- // When there is contrast adjustment, the calculations of brightness values are a bit different
- if (contrast !== 0) {
- // Determine how bright a pixel is, from 0 to 255 by summing three channels (R,G,B) multiplied by some coefficients
- b = (0.2125 * ((contrastFactor * (imagePixels.data[4 * currentHorizontalPixelIndex] - 128) + 128 )
- + brightness)) + (0.7154 * ((contrastFactor * (imagePixels.data[4 * (currentHorizontalPixelIndex + 1)] - 128) + 128)
- + brightness)) + (0.0721 * ((contrastFactor*(imagePixels.data[4*(currentHorizontalPixelIndex+2)]-128)+128) + brightness));
- } else {
- b = (0.2125 * (imagePixels.data[4*currentHorizontalPixelIndex] + brightness)) + (0.7154 * (imagePixels.data[4*(currentHorizontalPixelIndex + 1)]+ brightness)) + (0.0721 * (imagePixels.data[4*(currentHorizontalPixelIndex + 2)] + brightness));
+ // When there is contrast adjustment, the calculations of brightness values are a bit different
+ if (contrast !== 0) {
+ // Determine how bright a pixel is, from 0 to 255 by summing three channels (R,G,B) multiplied by some coefficients
+ b = (0.2125 * ((contrastFactor * (imagePixels.data[4 * currentHorizontalPixelIndex] - 128) + 128 )
+ + brightness)) + (0.7154 * ((contrastFactor * (imagePixels.data[4 * (currentHorizontalPixelIndex + 1)] - 128) + 128)
+ + brightness)) + (0.0721 * ((contrastFactor*(imagePixels.data[4*(currentHorizontalPixelIndex+2)]-128)+128) + brightness));
+ } else {
+ b = (0.2125 * (imagePixels.data[4*currentHorizontalPixelIndex] + brightness)) + (0.7154 * (imagePixels.data[4*(currentHorizontalPixelIndex + 1)]+ brightness)) + (0.0721 * (imagePixels.data[4*(currentHorizontalPixelIndex + 2)] + brightness));
+ }
+
+ if (black) {
+ b = Math.min(255-minBrightness,255-b); // Set minimum line curvature to value set by the user
+ z = Math.max(maxBrightness-b,0); // Set maximum line curvature to value set by the user
+ } else {
+ b = Math.max(minBrightness,b); // Set minimum line curvature to value set by the user
+ z = Math.max(maxBrightness-b,0); // Set maximum line curvature to value set by the user
+ }
+
+ // The magic of the script, determines how high / low the squiggle goes
+ r = config.amplitude * z / lineCount;
+
+ a += z / config.frequency;
+ currentLine.push([x,y + Math.sin(a)*r]);
}
-
- b = Math.max(minBrightness,b); // Set minimum line curvature to value set by the user
- z = Math.max(maxBrightness-b,0); // Set maximum line curvature to value set by the user
-
- // The magic of the script, determines how high / low the squiggle goes
- r = config.amplitude * z / lineCount;
-
- a += z / config.frequency;
- currentLine.push([x,y + Math.sin(a)*r]);
+ //currentLine.push([config.width, y]);
+ squiggleData.push(currentLine);
}
- //currentLine.push([config.width, y]);
- squiggleData.push(currentLine);
- }
- return squiggleData;
- }, [{
- config: Object.assign({}, this.settings),
- image: this.canvasData
- }])
- .then(result => {
- this.lines = [];
-
- result.forEach( line => {
- this.lines.push({values: line});
+ return squiggleData;
+ }, [{
+ config: Object.assign({}, this.settings),
+ image: this.canvasData
+ }])
+ .then(result => {
+ this.lines = [];
+ result.forEach( line => {
+ this.lines.push({values: line});
+ })
})
- })
- .catch(e => {
- console.error(e)
- })
- },
- onCapture() {
- this.webcam.img = this.$refs.webcam.capture();
- this.canvasData = this.$refs.webcam.getCanvasRaw();
- },
- onStarted(stream) {
- this.webcam.streaming = true;
- },
- onStopped(stream) {
- this.webcam.streaming = false;
- },
- onStop() {
- this.$refs.webcam.stop();
- },
- onStart() {
- this.$refs.webcam.start();
- },
- onError(error) {
- //console.log("On Error Event", error);
- },
- onCameras(cameras) {
- this.webcam.devices = cameras;
- //console.log("On Cameras Event", cameras);
- },
- onCameraChange(deviceId) {
- this.webcam.deviceId = deviceId;
- this.webcam.camera = deviceId;
- //console.log("On Camera Change Event", deviceId);
- },
- onInputSelected(type) {
- this.inputType = type;
+ .catch(e => {
+ console.error(e)
+ })
+ },
+ onCapture() {
+ this.webcam.img = this.$refs.webcam.capture();
+ this.canvasData = this.$refs.webcam.getCanvasRaw();
+ },
+ onStarted(stream) {
+ this.webcam.streaming = true;
+ },
+ onStopped(stream) {
+ this.webcam.streaming = false;
+ },
+ onStop() {
+ this.$refs.webcam.stop();
+ },
+ onStart() {
+ this.$refs.webcam.start();
+ },
+ onError(error) {
+ console.log("On Error Event", error);
+ },
+ onCameras(cameras) {
+ this.webcam.devices = cameras;
+ console.log("On Cameras Event", cameras);
+ },
+ onCameraChange(deviceId) {
+ this.webcam.deviceId = deviceId;
+ this.webcam.camera = deviceId;
+ },
+ onInputSelected(type) {
+ this.inputType = type;
+ }
}
}
-}
diff --git a/src/components/svgChartLine.vue b/src/components/svgChartLine.vue
index a0d23fc..6f8d3e5 100644
--- a/src/components/svgChartLine.vue
+++ b/src/components/svgChartLine.vue
@@ -1,15 +1,14 @@
-
+