Basically, when a button is clicked, it'll tell the mobile device to go to the camera. Once the camera takes a picture, it'll give me the image data (is it called the data URL?). This is my code to handle it:
var imagesrc = "data:image/jpeg;base64," + imageData;
var myimage = new Image(500, 500);
myimage.src = imagesrc; <---- to populate the object with the colored image
myimage.src = grayscale(myimage); <---- here I set it to the grayscale image
I want to call a method called grayscale()
and make it return the image that's been turned into grayscale. I tried this:
function grayscale(image){
var canvasContext = canvas.getContext('2d');
var imgW = image.width;
var imgH = image.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(image, 0, 0);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(>var y = 0; y < imgPixels.height; y++){
for(>var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
dataurl = canvas.toDataURL();
var newimg = "data:image/jpeg;base64," + dataurl;
return newimg;
}
But for some reason it doesn't work. It just doesn't display the grayscale image. I got the for loop code online and tweaked it.
Basically, when a button is clicked, it'll tell the mobile device to go to the camera. Once the camera takes a picture, it'll give me the image data (is it called the data URL?). This is my code to handle it:
var imagesrc = "data:image/jpeg;base64," + imageData;
var myimage = new Image(500, 500);
myimage.src = imagesrc; <---- to populate the object with the colored image
myimage.src = grayscale(myimage); <---- here I set it to the grayscale image
I want to call a method called grayscale()
and make it return the image that's been turned into grayscale. I tried this:
function grayscale(image){
var canvasContext = canvas.getContext('2d');
var imgW = image.width;
var imgH = image.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(image, 0, 0);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(>var y = 0; y < imgPixels.height; y++){
for(>var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
dataurl = canvas.toDataURL();
var newimg = "data:image/jpeg;base64," + dataurl;
return newimg;
}
But for some reason it doesn't work. It just doesn't display the grayscale image. I got the for loop code online and tweaked it.
Share Improve this question asked May 11, 2016 at 22:57 Mingle LiMingle Li 1,3501 gold badge15 silver badges39 bronze badges 3 |3 Answers
Reset to default 6There are several reasons this does not work. It would be a good thing for you to start checking console output to track bugs. Firefox "F12" for example, would tell you that for(>var ...)
is a problem. ;)
Did you declare canvas
somewhere, outside the code you shared with us? Is dataurl
declared? The prefixing of toDataUrl
is not needed...
Here's a basic html file I typed around your for-loop, that does turn "test.png" to grey. Maybe you want to save it somewhere, put a png into the same folder, and start editing stuff step by step, instead of copying code. If you feel up for a challenge try making it pass http://jslint.com/! (You'd have to replace the for loop with while loops, I guess). :)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas/ImgData Test</title>
</head>
<body>
<canvas id="output"></canvas>
<script>
var cnv = document.getElementById('output');
var cnx = cnv.getContext('2d');
function grey(input) {
cnx.drawImage(myimage, 0 , 0);
var width = input.width;
var height = input.height;
var imgPixels = cnx.getImageData(0, 0, width, height);
for(var y = 0; y < height; y++){
for(var x = 0; x < width; x++){
var i = (y * 4) * width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
cnx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
}
var myimage = new Image();
myimage.onload = function() {
grey(myimage);
}
myimage.src = "test.png";
</script>
</body>
</html>
i know you are looking for converting dataURI to grayscale but, if you want to convert the video feedback itself to grayscale or convert any image to grayscale you can use this code.
.gray {
filter: grayscale();
}
<!--hey use this style to show in gray scale. can even use to convert image to grayscale-->
<video id="camera-stream" class="gray" ></video>
You shouldn't take the average of the 3 colour components, as they vary greatly in brightness (100% green is a lot brighter than 100% blue). The TV systems (PAL and NTSC) define the brightness of the greyscale picture as 29.9% Red + 58.7% Green + 11.4% Blue.
toDataURL
already returns a full data URL, you don't need to prefix it (and it won't be a jpeg anyway) – Bergi Commented May 11, 2016 at 23:27