Pretty new to JavaScript.
I'm building a site that compares the template image with the user's input and builds some image processing directives. The template image is stored in the site's folder.
$(function() {
$("#btnDirective").click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('imgs/templates/human.png');
}
function getImageData(source) {
var image = new Image();
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
for (var px = 0, cx = canvas.width * canvas.height * 4; px < cx; px += 4)
if (data[px+3] != 255 && data[px+3] != 0)
console.log("Alpha: " + data[px+3]);
};
image.src = source;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="scripts/jquery-1.11.3.min.js"></script>
<script src="scripts/script.js"></script>
</head>
<body>
<button id="btnDirective">Generate</button>
</body>
</html>
'imgs/templates/human.png' contains a lot of semitransparent values, that are never fetched:
So you are trying to get the integer values for each pixel where it's alpha value of neither 0 nor 255?
Well, your image has pixels that are either full transparent, or they are solid white/black. So you will have no partially-transparent pixels.
See the image of the chili pepper emoji from Emojipedia that is used below. Around ~6% of its pixels are partially transparent (around the borders).
$(function() {
$('#btnDirective').click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('https://i.imgur.com/4LzuX3G.png');
getImageData('https://i.imgur.com/R7g697w.png'); // Using a testable image
}
function getImageData(source) {
var image = new Image();
image.crossOrigin = 'Anonymous'; // This allows Imgur CORS...
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
document.body.appendChild(canvas); // Add canvas to body...
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
var pixels = canvas.width * canvas.height;
var alphaValues = [];
for (var px = 0, cx = pixels * 4; px < cx; px += 4) {
if (data[px + 3] != 255 && data[px + 3] != 0) {
alphaValues.push(data[px + 3]);
}
}
var nonAlphaPixels = (alphaValues.length / pixels * 100).toFixed(2);
console.log('Alpha (' + nonAlphaPixels + '%): ' + alphaValues.join(','));
};
image.src = source;
}
function drawPartialPixels(imageData) {
}
body { background: #444; }
#btnDirective { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnDirective">Generate</button>
Here is an example of drawing only the partial pixels.
$(function() {
$('#btnDirective').click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('https://i.imgur.com/R7g697w.png', onImageLoad);
}
function getImageData(source, onLoadFn) {
var image = new Image();
image.src = source;
image.crossOrigin = 'Anonymous'; // This allows Imgur CORS...
image.onload = function() {
onLoadFn(this);
};
}
function onImageLoad(image) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = canvas.width * canvas.height;
for (var px = 0, cx = pixels * 4; px < cx; px += 4) {
var partialAlpha = imageData.data[px + 3] != 255 && imageData.data[px + 3] != 0;
imageData.data[px + 0] = partialAlpha ? 255 : 0;
imageData.data[px + 1] = partialAlpha ? 0 : 0;
imageData.data[px + 2] = partialAlpha ? 0 : 0;
imageData.data[px + 3] = partialAlpha ? 255 : 0;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(imageData, 0, 0);
document.body.appendChild(canvas); // Add canvas to body...
}
body { background: #444; }
#btnDirective { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnDirective">Generate</button>
Related
How can i generate outline effect on text image in java script?
The closest solution on StackOverflow I found is How to add stroke/outline to transparent PNG image in JavaScript canvas
I have tried this code but it is working fine in any shape
But my requirement is to draw outline like below images for example
// canvas related variables
var canvas = document.getElementById("canvas");
// canvas.width = 600;
// canvas.height = 400;
var ctx = canvas.getContext("2d");
// variables used in pixel manipulation
var canvases = [];
var imageData, data, imageData1, data1;
// size of sticker outline
var strokeWeight = 8;
// true/false function used by the edge detection method
var defineNonTransparent = function(x, y) {
return (data1[(y * cw + x) * 4 + 3] > 0);
}
var img = new Image();
document.querySelector('#fileinput').addEventListener('change', function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(event) {
let innerImageURL = event.target.result;
console.log(innerImageURL);
img = new Image();
img.crossOrigin = "anonymous";
img.onload = start;
img.src = innerImageURL;
// img.src = "https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fsun.png?v=1564472507237";
};
reader.readAsDataURL(file);
});
// the image receiving the sticker effect
// var img = new Image();
// img.crossOrigin = "anonymous";
// img.onload = start;
// img.src = "https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fsun.png?v=1564472507237";
function start() {
console.log(img.width)
console.log(img.height)
// resize the main canvas to the image size
canvas.width = cw = img.width;
canvas.height = ch = img.height;
// draw the image on the main canvas
ctx.drawImage(img, 0, 0);
// Move every discrete element from the main canvas to a separate canvas
// The sticker effect is applied individually to each discrete element and
// is done on a separate canvas for each discrete element
while (moveDiscreteElementToNewCanvas()) {}
// add the sticker effect to all discrete elements (each canvas)
for (var i = 0; i < canvases.length; i++) {
addStickerEffect(canvases[i], strokeWeight);
ctx.drawImage(canvases[i], 0, 0);
}
// redraw the original image
// (necessary because the sticker effect
// slightly intrudes on the discrete elements)
ctx.drawImage(img, 0, 0);
}
//
function addStickerEffect(canvas, strokeWeight) {
var url = canvas.toDataURL();
var ctx1 = canvas.getContext("2d");
var pts = canvas.outlinePoints;
addStickerLayer(ctx1, pts, strokeWeight);
var imgx = new Image();
imgx.onload = function() {
ctx1.drawImage(imgx, 0, 0);
}
imgx.src = url;
}
function addStickerLayer(context, points, weight) {
imageData = context.getImageData(0, 0, canvas.width, canvas.height);
data1 = imageData.data;
var points = geom.contour(defineNonTransparent);
defineGeomPath(context, points)
context.lineJoin = "round";
context.lineCap = "round";
context.strokeStyle = "white";
context.lineWidth = weight;
context.stroke();
}
// This function finds discrete elements on the image
// (discrete elements == a group of pixels not touching
// another groups of pixels--e.g. each individual sprite on
// a spritesheet is a discreet element)
function moveDiscreteElementToNewCanvas() {
// get the imageData of the main canvas
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data1 = imageData.data;
// test & return if the main canvas is empty
// Note: do this b/ geom.contour will fatal-error if canvas is empty
var hit = false;
for (var i = 0; i < data1.length; i += 4) {
if (data1[i + 3] > 0) {
hit = true;
break;
}
}
if (!hit) {
return;
}
// get the point-path that outlines a discrete element
var points = geom.contour(defineNonTransparent);
// create a new canvas and append it to page
var newCanvas = document.createElement('canvas');
newCanvas.width = canvas.width;
newCanvas.height = canvas.height;
// newCanvas.style.display = "none";
document.body.appendChild(newCanvas);
canvases.push(newCanvas);
var newCtx = newCanvas.getContext('2d');
// attach the outline points to the new canvas (needed later)
newCanvas.outlinePoints = points;
// draw just that element to the new canvas
defineGeomPath(newCtx, points);
newCtx.save();
newCtx.clip();
newCtx.drawImage(canvas, 0, 0);
newCtx.restore();
// remove the element from the main canvas
defineGeomPath(ctx, points);
ctx.save();
ctx.clip();
ctx.globalCompositeOperation = "destination-out";
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
return (true);
}
// utility function
// Defines a path on the canvas without stroking or filling that path
function defineGeomPath(context, points) {
context.beginPath();
context.moveTo(points[0][0], points[0][1]);
for (var i = 1; i < points.length; i++) {
context.lineTo(points[i][0], points[i][1]);
}
context.lineTo(points[0][0], points[0][1]);
context.closePath();
}
////////////////////////////
// Edge Detection
///////////////////////////
(function() {
geom = {};
geom.contour = function(grid, start) {
var s = start || d3_geom_contourStart(grid), // starting point
c = [], // contour polygon
x = s[0], // current x position
y = s[1], // current y position
dx = 0, // next x direction
dy = 0, // next y direction
pdx = NaN, // previous x direction
pdy = NaN, // previous y direction
i = 0;
do {
// determine marching squares index
i = 0;
if (grid(x - 1, y - 1)) i += 1;
if (grid(x, y - 1)) i += 2;
if (grid(x - 1, y)) i += 4;
if (grid(x, y)) i += 8;
// determine next direction
if (i === 6) {
dx = pdy === -1 ? -1 : 1;
dy = 0;
} else if (i === 9) {
dx = 0;
dy = pdx === 1 ? -1 : 1;
} else {
dx = d3_geom_contourDx[i];
dy = d3_geom_contourDy[i];
}
// update contour polygon
if (dx != pdx && dy != pdy) {
c.push([x, y]);
pdx = dx;
pdy = dy;
}
x += dx;
y += dy;
} while (s[0] != x || s[1] != y);
return c;
};
// lookup tables for marching directions
var d3_geom_contourDx = [1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 0, 0, -1, 0, -1, NaN],
d3_geom_contourDy = [0, -1, 0, 0, 0, -1, 0, 0, 1, -1, 1, 1, 0, -1, 0, NaN];
function d3_geom_contourStart(grid) {
var x = 0,
y = 0;
// search for a starting point; begin at origin
// and proceed along outward-expanding diagonals
while (true) {
if (grid(x, y)) {
return [x, y];
}
if (x === 0) {
x = y + 1;
y = 0;
} else {
x = x - 1;
y = y + 1;
}
}
}
})();
#canvas {
background: #f0f0f0;
border-radius: 5px;
}
body {
background-color: #333;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
margin: 0;
}
* {
box-sizing: border-box;
}
#source {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link rel='stylesheet' href='https://code.getmdl.io/1.3.0/material.indigo-pink.min.css'>
</head>
<body>
<div class='mdl-grid'>
<div class='mdl-cell mdl-cell--4-col'>
<label id='buttonUpload' for='fileinput' class='mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent'>
<input type='file' id='fileinput' style='display: none'>
Upload
</label>
<div class='mdl-tooltip' for='buttonUpload'>
Upload the image to put inside the marker
</div>
</div>
</div>
<!-- <h4>Original Image</h4> -->
<!-- <img height="200px" width="200px" src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fsun.png?v=1564472507237"> -->
<h4>Canvas with sticker effect applied</h4>
<div class="container">
<canvas id="canvas" width="600" height="400"></canvas><br>
</div>
<h4>Each discrete element of the image is processed on a separate canvas<br>Temp-canvases are shown below for illustration purposes only.</h4>
</body>
</html>
I was thinking about how to get something close to what you show in your image:
Maybe if we draw the image offset at different angles we can get something close to that:
var s = 16, x = 25, y = 25;
var ctx = document.getElementById('canvas1').getContext('2d')
var img = new Image;
img.onload = draw1;
img.src = "https://imgur.com/download/oXfw9nD/";
function draw1() {
for (i = 0; i < 360; i++)
ctx.drawImage(img, x + Math.sin(i) * s, y + Math.cos(i) * s);
ctx.filter = 'invert(100)'
ctx.drawImage(img, x, y);
}
<canvas id=canvas1 width=460 height=160></canvas>
You can also add some blur to soften the edges, take a look:
var s = 6, x = 25, y = 25;
var ctx = document.getElementById('canvas1').getContext('2d')
var img = new Image;
img.onload = draw1;
img.src = "https://imgur.com/download/oXfw9nD/";
function draw1() {
ctx.filter = 'blur(5px)'
for (i = 0; i < 360; i++)
ctx.drawImage(img, x + Math.sin(i) * s, y + Math.cos(i) * s);
ctx.globalCompositeOperation = "source-in";
ctx.filter = 'invert(100)'
ctx.globalCompositeOperation = "source-over";
ctx.drawImage(img, x, y);
}
<canvas id=canvas1 width=460 height=160></canvas>
That should get you closer to what you need
I have been trying to put filters (like brightness, contrast) on image loaded in canvas.
Below is a snippet of what I am doing
/******Loading Image in Canvas******/
let canvas = document.getElementById('demo');
let ctx = canvas.getContext('2d');
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = 220;
canvas.height = 250;
ctx.drawImage(img,0,0,canvas.width,canvas.height);
}
img.src = event.target.result;
self.oldImg = event.target.result;
}
reader.readAsDataURL(xevents.target.files[0]);
I have added brightness, contrast logic and is working fine on the image.
The Issue actually arise when I do any operation on image like resizing the canvas(using jquery UI resizeable). The filters applied get lost.
Below is the snippet for redrawing on canvas when resizes.
$(".stretch").resizable({ resize: function(event, ui) {
$("#demo", this).each(function() {
$(this).attr({ width: ui.size.width, height: ui.size.height });
self.reDraw(this);
});
} });
reDraw () {
var img = new Image();
var canvas = document.getElementById('demo');
var c = canvas.getContext("2d");
img.src = this.oldImg;
c.drawImage(img, 0, 0, canvas.width, canvas.height);
}
I believe, since it is creating again a new image object (new Image()), the filters are getting lost.
Can anyone help me on this. I want the filters to be retained as I resize the canvas.
Appreciated !! Thanks
Update
process (type, amount) {
var img = new Image();
var canvas = document.getElementById('demo');
var c = canvas.getContext("2d");
img.src = this.oldImg;
c.drawImage(img, 0, 0, canvas.width, canvas.height);
let imgData = c.getImageData(0, 0, canvas.width, canvas.height);
let data = imgData.data;
if(type === 'b') {
for (let i = 0; i < data.length; i += 4) {
data[i] += amount;
data[i + 1] += amount;
data[i + 2] += amount;
}
}
if(type === 'c') {
amount = (amount/100) + 1; //convert to decimal & shift range: [0..2]
let intercept = 128 * (1 - amount);
for(let i=0;i<data.length;i+=4){ //r,g,b,a
data[i] = data[i]*amount + intercept;
data[i+1] = data[i+1]*amount + intercept;
data[i+2] = data[i+2]*amount + intercept;
}
}
c.putImageData(imgData, 0, 0);
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have a set of coordinates and for every pair I'd like to place a SVG on the canvas. The problem is in getCircle function. The SVG doesn't work, but if I draw a circle(see commented code) it works.
function getCircle() {
var circle = document.createElement("canvas"),
ctx = circle.getContext("2d"),
r2 = radius + blur;
circle.width = circle.height = r2 * 2;
/*
ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2;
ctx.shadowBlur = blur;
ctx.shadowColor = "purple";
ctx.beginPath();
ctx.arc(-r2, -r2, radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
*/
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = "https://upload.wikimedia.org/wikipedia/en/0/09/Circle_Logo.svg";
return circle;
}
var radius = 5;
var blur = 1;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 200;
var circle = getCircle();
ctx.clearRect(0, 0, canvas.width, canvas.height);
var data = [[38,20,2]];
for (var i = 0, len = data.length, p; i < len; i++) {
p = data[i];
ctx.drawImage(circle, p[0] - radius, p[1] - radius);
}
#c {
width: 400px;
height: 200px;
}
<canvas id="c"></canvas>
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 200;
var data = [[0,20,2],[125,20,2],[250,20,2]];
drawImage();
function drawImage() {
var img = new Image();
img.onload = function() {
for (var i = 0, len = data.length, p; i < len; i++) {
p = data[i];
ctx.drawImage(this, p[0] , p[1] , 150, 150);
}
};
img.src = "https://upload.wikimedia.org/wikipedia/en/0/09/Circle_Logo.svg";
}
#c {
width: 400px;
height: 200px;
}
<canvas id="c"></canvas>
in img.onload() draw your image in specified position with widht and height using drawImage().
I am using this js: http://www.jqueryscript.net/other/jQuery-Image-Processing-Plugin-With-Canvas-Tancolor.html
What this plugin is doing, it is converting my canvas to black and white and saving it in an IMG tag on my web page.
Here is the javascript this plugin is using:
(function ($) {
$.fn.tancolor = function(options) {
var settings = $.extend({
mode: 'grayscale',
r_weight: 0.34,
g_weight: 0.5,
b_weight: 0.16,
r_intensity: 1,
g_intensity: 1,
b_intensity: 1,
load: null
}, options );
var r_weight;
var g_weight;
var b_weight;
var r_intensity;
var g_intensity;
var b_intensity;
// settings value
switch(settings.mode){
case 'grayscale':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 1;
b_intensity = 1;
break;
case 'red':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 255;
g_intensity = 1;
b_intensity = 1;
break;
case 'green':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 255;
b_intensity = 1;
break;
case 'blue':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 1;
b_intensity = 255;
break;
default:
r_weight = settings.r_weight;
g_weight = settings.g_weight;
b_weight = settings.b_weight;
r_intensity = settings.r_intensity;
g_intensity = settings.g_intensity;
b_intensity = settings.b_intensity;
break;
}
// convert image to canvas
var img = document.getElementById($(this).attr("id"));
if(settings.load){
img.src = settings.load;
return;
}
var canvas = convertImageToCanvas(img);
var ctx = canvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, img.width, img.height)
$(this).replaceWith(canvas);
// Processing image data
var data = imageData.data;
for(var i = 0; i < data.length; i += 4) {
var brightness = r_weight * data[i] + g_weight * data[i + 1] + b_weight * data[i + 2];
// red
data[i] = r_intensity * brightness;
// green
data[i + 1] = g_intensity * brightness;
// blue
data[i + 2] = b_intensity * brightness;
}
ctx.putImageData(imageData, 0, 0);
$('#'+$(this).attr("id")).each(function(i,e){
var img = e.toDataURL("image/png");
$(e).replaceWith( $('<img src="' + img + '"/>').attr({width: $(e).attr("width"), height: $(e).attr("height"), style: $(e).attr("style") }) ) });
// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
if(image.id) {
canvas.id = image.id;
}
if(image.className) {
canvas.className = image.className;
}
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
};
}(jQuery));
What I actually want is just convert my canvas to black and white but saving it in canvas tag only on web page and not as IMG tag as I am than after downloading the greyscale canvas merging with another canvas from the app.
Any help will be appreciated.
Thanks
To grayscale a non-transparent image, on compatible browsers, you could simply [if Safari didn't had a strange bug with that, you should have been able to] use the context.globalCompositeOperation property and set it to 'luminosity' after you've drawn a solid color, before falling to the getImageData solution :
var img = new Image();
var ctx = canvas.getContext('2d');
img.onload = function() {
// set the canvas' size
canvas.width = this.width;
canvas.height = this.height;
// first fill a rect
ctx.fillStyle = 'white'
ctx.fillRect(0, 0, canvas.width, canvas.height);
// set the gCO
ctx.globalCompositeOperation = 'luminosity';
// if the browser doesn't support Blend Modes
console.log(ctx.globalCompositeOperation)
if (ctx.globalCompositeOperation !== 'luminosity')
fallback(this);
else {
// draw the image
ctx.drawImage(this, 0, 0);
// reset the gCO
ctx.globalCompositeOperation = 'source-over';
}
}
img.crossOrigin = "anonymous";
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
function fallback(img) {
// first remove our black rectangle
ctx.clearRect(0, 0, canvas.width, canvas.height);
//draw the image
ctx.drawImage(img, 0, 0);
// get the image data
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var d = imgData.data;
// loop through all pixels
// each pixel is decomposed in its 4 rgba values
for (var i = 0; i < d.length; i += 4) {
// get the medium of the 3 first values
var med = (d[i] + d[i + 1] + d[i + 2]) / 3;
// set it to each value
d[i] = d[i + 1] = d[i + 2] = med;
}
// redraw the new computed image
ctx.putImageData(imgData, 0, 0);
}
<canvas id="canvas"></canvas>
But since Safari has a bug and that the gCO solution (which is faster, but I don't think it's important for you) remove the transparent pixels, here is just the previous fallback, which is a simpler code than the one you got. I hope you'll be able to read it.
var img = new Image();
var ctx = canvas.getContext('2d');
img.onload = function() {
// set the canvas' size
canvas.width = this.width;
canvas.height = this.height;
//draw the image
ctx.drawImage(this, 0, 0);
// get the image data
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var d = imgData.data;
// loop through all pixels
// each pixel is decomposed in its 4 rgba values
for (var i = 0; i < d.length; i += 4) {
// get the medium of the 3 first values ( (r+g+b)/3 )
var med = (d[i] + d[i + 1] + d[i + 2]) / 3;
// set it to each value (r = g = b = med)
d[i] = d[i + 1] = d[i + 2] = med;
// we don't touch the alpha
}
// redraw the new computed image
ctx.putImageData(imgData, 0, 0);
}
img.crossOrigin = "anonymous";
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
<canvas id="canvas"></canvas>
I'm using JQuery http://www.xarg.org/project/jquery-webcam-plugin/
I want take a photo and show using canvas, without upload photo.
var pos = 0, ctx = null, saveCB, image = [];
var canvas = document.createElement('canvas');
canvas.setAttribute('width', 320);
canvas.setAttribute('height', 240);
ctx = canvas.getContext('2d');
image = ctx.getImageData(0, 0, 320, 240);
var saveCB = function (data) {
var col = data.split(';');
var img = image;
for (var i = 0; i < 320; i++) {
var tmp = parseInt(col[i]);
img.data[pos + 0] = (tmp >> 16) & 0xff;
img.data[pos + 1] = (tmp >> 8) & 0xff;
img.data[pos + 2] = tmp & 0xff;
img.data[pos + 3] = 0xff;
pos += 4;
}
if (pos >= 4 * 320 * 240) {
ctx.putImageData(img, 0, 0);
foto = canvas.toDataURL("image/png");
//document.getElementById('foto').value = foto;
pos = 0;
}
};
$("#camera").webcam({
width: 320,
height: 240,
mode: "callback",
swffile: '#Url.Content("~/Content/js/jscam_canvas_only.swf")',
onSave: saveCB,
onCapture: function () {
webcam.save();
}
});
$('#upload').click(function () {
webcam.capture();
return false;
});
To show in canvas I need create a new a new tag, like this?
<canvas id="canvas" width="320" height="240"></canvas>
The button to take photo
<input id="upload" class="submit submit-blue" type="button" value="Tirar foto">
Solution
I forgot load event, to get canvas element.
window.addEventListener("load", function() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
ctx = document.getElementById("canvas").getContext("2d");
ctx.clearRect(0, 0, 320, 240);
image = ctx.getImageData(0, 0, 320, 240);
}
}, false);