If statement changing image to greyscale - javascript

currently i have an image converted to greyscale, it does this on the click of a button. I need to be able to remove this function either by using the same button or another button. I thought this would be possible by using an if statement although im not sure how to do this.
<html>
<body>
<script>
function greyscale(){
//get canvas
var canvas = document.getElementById("canvas");
//get the context property
var ctx = canvas.getContext('2d');
//get image
var image = document.getElementById("imgSrc");
//draw image to canvas
ctx.drawImage(image,0,0);
//get the image data
var imageData = ctx.getImageData(0,0,130,130);
//get the pixel data
var px = imageData.data;
//get entire length of pixel data
var length = px.length;
//loop and manipulate the pixels
for(var i=0;i<length;i+=4){
var redPx = px[i];
var greenPx = px[i+1];
var bluePx = px[i+2];
var alphaPx = px[i+3];
//create greyscale sub pixel
var greyscale = redPx*.3 + greenPx * .59 + bluePx * .11;
//store each subpixel as that greyscale subpixel
px[i] = greyscale;
px[i+1] = greyscale;
px[i+2] = greyscale;
}
//put the manipulated image data back into the canvas
ctx.putImageData(imageData,0,0);
}
</script><img src="flower.jpg" id="imgSrc"/>
<canvas id="canvas" width="130" height="130"></canvas>
<br>
</script>
<input id="btngreyscale" type="button" value="Greyscale" onclick="greyscale();" />
<input id="btngreyscaleoff" type="button" value="Greyscale Off" onclick="loadImage();" />
<br>
<input type="radio" name="zing" id="on" checked/>on
<input type="radio" name="zing" id="off"/>off
<script type="text/javascript">
if (document.getElementById('btngreyscale').checked) {
alert('on');
} else {
(document.getElementById('btngreyscaleoff').checked)
alert('off');
}
</script>
</body>
</html>

As Roman hocke already said, you are not able to use the greyscale to turn it back to a colorful image, since you threw some information away. To go back to a colorful image you just have to redraw the first image.
so in your code this would be:
(document.getElementById('btngreyscaleoff').checked)
alert('off');
ctx.drawImage(image,0,0);
}
This can be done that easily because you have already saved the image object in the DOM.

Related

Trying to drag and drop onto an SVG canvas with accurate coordinates

I am trying to implement drag and drop an image element onto an SVG canvas but the elements are not in the same div. I have tried to use clientX and clientY properties but they are out by about 20 pixels when I come to drop the element. I think the problem is that the SVG coordinates work from the top of the root SVG element but drag and drop coordinates are from the visible view port. When I try to release the rock image on the canvas it just seems to go to any random place on it and sometimes off the canvas completely.
I have uploaded all my code to https://github.com/kiwiheretic/gravity
(It shouldn't be too difficult to just clone the repo and open index.html within the browser to see the problem.)
The relevant HTML code is as follows:
<div style="background-color:black; width: min-content;">
<svg id="space" width="600" height="400" xmlns="http://www.w3.org/2000/svg" onload="makeDraggable(evt)">
</svg>
</div>
<div id="object-block-1" class="objects">
<div class="box">
<img src="asteroid.png" alt="asteroid">
</div>
</div>
</div>
The relevant javascript code is:
var objblock = document.getElementById("object-block-1");
objblock.addEventListener("dragstart", function(evt) {
draggedObject = evt.target;
});
objbl
objblock.addEventListener("dragend", function(evt) {
var x = evt.clientX;
var y = evt.clientY;
var src = draggedObject.getBoundingClientRect();
console.log([x,y]);
var space = document.getElementById("space");
var tgt = space.getBoundingClientRect();
if (doesPointCollide(x,y,tgt)) {
//asteroid = makeAsteroid(x, y, 50, 50);
//space.appendChild(asteroid);
}
});
objblock.addEventListener("drag", function(evt) {
var space = document.getElementById("space");
var rect = space.getBoundingClientRect();
var src = draggedObject.getBoundingClientRect();
var x = (src.x - rect.x) + evt.clientX;
var y = (src.y + rect.y) + evt.clientY;
document.getElementsByName("drag-x")[0].value = parseInt(x);
document.getElementsByName("drag-y")[0].value = parseInt(y);
});
I am using the right hand input boxes as kind of a debugging aid. I am not sure why drag-x and drag-y are not resolving to suitable SVG coordinates within the canvas and what needs to be done to fix that.
Any idea what javascript mouse event attributes and element attributes to work out my SVG coordinates for drag and drop?

JS: Function works manually in console but not executed automatically in code

I copied this code snippet from here: https://codepen.io/duketeam/pen/ALEByA
This code is supposed to load a picture and make it grayscale after clicking on the button.
I want to change the code such that the picture comes out immediately as grayscale without having to click on the button, hence why I commented it out and included makeGray() in the onload part of the <input...>. But this doesnt work. Where am I going wrong here?
I have tried to leave out the makeGray()and just upload the picture and type makeGray() in the console and it does its job perfectly fine, but I need it to execute automatically. I also tried to just put all the code from the makeGray() function in the upload() function but also here it won't trigger.
var image = null;
function upload() {
//Get input from file input
var fileinput = document.getElementById("finput");
//Make new SimpleImage from file input
image = new SimpleImage(fileinput);
//Get canvas
var canvas = document.getElementById("can");
//Draw image on canvas
image.drawTo(canvas);
}
function makeGray() {
//change all pixels of image to gray
for (var pixel of image.values()) {
var avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;
pixel.setRed(avg);
pixel.setGreen(avg);
pixel.setBlue(avg);
}
//display new image
var canvas = document.getElementById("can");
image.drawTo(canvas);
}
<script src="https://www.dukelearntoprogram.com/course1/common/js/image/SimpleImage.js">
</script>
<h1>Convert Image to Grayscale</h1>
<canvas id="can"></canvas>
<p>
<input type="file" multiple="false" accept="image/*" id="finput" onchange="upload();makeGray()">
</p>
<p>
<!---- <input type="button" value="Make Grayscale" onclick="makeGray()" -->
</p>
<script src="./index.js"></script>
There's something you need to wait for, but I'm not sure exactly what it is. If you wrap the function in a setTimeout, it works fine. You might want to wait for a few more milliseconds for clients with slower systems or bigger files. If you ever figure out what is taking a while to do, you can instead use .then or await just to be safe.
var image = null;
function upload() {
//Get input from file input
var fileinput = document.getElementById("finput");
//Make new SimpleImage from file input
image = new SimpleImage(fileinput);
//Get canvas
var canvas = document.getElementById("can");
setTimeout(() => {
//change all pixels of image to gray
for (var pixel of image.values()) {
var avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;
pixel.setRed(avg);
pixel.setGreen(avg);
pixel.setBlue(avg);
}
image.drawTo(canvas);
}, 100);
}
<script src="https://www.dukelearntoprogram.com/course1/common/js/image/SimpleImage.js">
</script>
<h1>Convert Image to Grayscale</h1>
<canvas id="can"></canvas>
<p>
<input type="file" multiple="false" accept="image/*" id="finput" onchange="upload();">
</p>
<script src="./index.js"></script>

Does every blank canvas produce the same data URL regardless of the size of the canvas?

I wanted to know if every blank canvas produces the same data URL so that I can be able to detect if a canvas has something drawn in it or
whether it is empty. Is this also true regardless of size of the canvas?
It does not:
<canvas id="one" width="25" height="25"></canvas>
<canvas id="two" width="30" height="30"></canvas>
Javascript:
var canvas1 = document.getElementById("one");
var dataUrl1 = canvas1.toDataURL();
var canvas2 = document.getElementById("two");
var dataUrl2 = canvas2.toDataURL();
console.log(dataUrl1);
console.log(dataUrl2);
https://jsfiddle.net/r1sekxLa/
You can subscribe to canvas draw event to see if it was changed.

How to convert canvas image to standard img? [duplicate]

Is there possibility to convert the image present in a canvas element into an image representing by img src?
I need that to crop an image after some transformation and save it. There are a view functions that I found on the internet like: FileReader() or ToBlop(), toDataURL(), getImageData(), but I have no idea how to implement and use them properly in JavaScript.
This is my html:
<img src="http://picture.jpg" id="picture" style="display:none"/>
<tr>
<td>
<canvas id="transform_image"></canvas>
</td>
</tr>
<tr>
<td>
<div id="image_for_crop">image from canvas</div>
</td>
</tr>
In JavaScript it should look something like this:
$(document).ready(function() {
img = document.getElementById('picture');
canvas = document.getElementById('transform_image');
if(!canvas || !canvas.getContext){
canvas.parentNode.removeChild(canvas);
} else {
img.style.position = 'absolute';
}
transformImg(90);
ShowImg(imgFile);
}
function transformImg(degree) {
if (document.getElementById('transform_image')) {
var Context = canvas.getContext('2d');
var cx = 0, cy = 0;
var picture = $('#picture');
var displayedImg = {
width: picture.width(),
height: picture.height()
};
var cw = displayedImg.width, ch = displayedImg.height
Context.rotate(degree * Math.PI / 180);
Context.drawImage(img, cx, cy, cw, ch);
}
}
function showImg(imgFile) {
if (!imgFile.type.match(/image.*/))
return;
var img = document.createElement("img"); // creat img object
img.id = "pic"; //I need set some id
img.src = imgFile; // my picture representing by src
document.getElementById('image_for_crop').appendChild(img); //my image for crop
}
How can I change the canvas element into an img src image in this script? (There may be some bugs in this script.)
canvas.toDataURL() will provide you a data url which can be used as source:
var image = new Image();
image.id = "pic";
image.src = canvas.toDataURL();
document.getElementById('image_for_crop').appendChild(image);
Complete example
Here's a complete example with some random lines. The black-bordered image is generated on a <canvas>, whereas the blue-bordered image is a copy in a <img>, filled with the <canvas>'s data url.
// This is just image generation, skip to DATAURL: below
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d");
// Just some example drawings
var gradient = ctx.createLinearGradient(0, 0, 200, 100);
gradient.addColorStop("0", "#ff0000");
gradient.addColorStop("0.5" ,"#00a0ff");
gradient.addColorStop("1.0", "#f0bf00");
ctx.beginPath();
ctx.moveTo(0, 0);
for (let i = 0; i < 30; ++i) {
ctx.lineTo(Math.random() * 200, Math.random() * 100);
}
ctx.strokeStyle = gradient;
ctx.stroke();
// DATAURL: Actual image generation via data url
var target = new Image();
target.src = canvas.toDataURL();
document.getElementById('result').appendChild(target);
canvas { border: 1px solid black; }
img { border: 1px solid blue; }
body { display: flex; }
div + div {margin-left: 1ex; }
<div>
<p>Original:</p>
<canvas id="canvas" width=200 height=100></canvas>
</div>
<div id="result">
<p>Result via <img>:</p>
</div>
See also:
MDN: canvas.toDataURL() documentation
Do this. Add this to the bottom of your doc just before you close the body tag.
<script>
function canvasToImg() {
var canvas = document.getElementById("yourCanvasID");
var ctx=canvas.getContext("2d");
//draw a red box
ctx.fillStyle="#FF0000";
ctx.fillRect(10,10,30,30);
var url = canvas.toDataURL();
var newImg = document.createElement("img"); // create img tag
newImg.src = url;
document.body.appendChild(newImg); // add to end of your document
}
canvasToImg(); //execute the function
</script>
Of course somewhere in your doc you need the canvas tag that it will grab.
<canvas id="yourCanvasID" />
I´ve found two problems with your Fiddle, one of the problems is first in Zeta´s answer.
the method is not toDataUrl(); is toDataURL(); and you forgot to store the canvas in your variable.
So the Fiddle now works fine http://jsfiddle.net/gfyWK/12/
I hope this helps!
canvas.toDataURL is not working if the original image URL (either relative or absolute) does not belong to the same domain as the web page. Tested from a bookmarklet and a simple javascript in the web page containing the images.
Have a look to David Walsh working example. Put the html and images on your own web server, switch original image to relative or absolute URL, change to an external image URL. Only the first two cases are working.
Corrected the Fiddle - updated shows the Image duplicated into the Canvas...
And right click can be saved as a .PNG
http://jsfiddle.net/gfyWK/67/
<div style="text-align:center">
<img src="http://imgon.net/di-M7Z9.jpg" id="picture" style="display:none;" />
<br />
<div id="for_jcrop">here the image should apear</div>
<canvas id="rotate" style="border:5px double black; margin-top:5px; "></canvas>
</div>
Plus the JS on the fiddle page...
Cheers
Si
Currently looking at saving this to File on the server --- ASP.net C# (.aspx web form page) Any advice would be cool....

Can I get image from canvas element and use it in img src tag?

Is there possibility to convert the image present in a canvas element into an image representing by img src?
I need that to crop an image after some transformation and save it. There are a view functions that I found on the internet like: FileReader() or ToBlop(), toDataURL(), getImageData(), but I have no idea how to implement and use them properly in JavaScript.
This is my html:
<img src="http://picture.jpg" id="picture" style="display:none"/>
<tr>
<td>
<canvas id="transform_image"></canvas>
</td>
</tr>
<tr>
<td>
<div id="image_for_crop">image from canvas</div>
</td>
</tr>
In JavaScript it should look something like this:
$(document).ready(function() {
img = document.getElementById('picture');
canvas = document.getElementById('transform_image');
if(!canvas || !canvas.getContext){
canvas.parentNode.removeChild(canvas);
} else {
img.style.position = 'absolute';
}
transformImg(90);
ShowImg(imgFile);
}
function transformImg(degree) {
if (document.getElementById('transform_image')) {
var Context = canvas.getContext('2d');
var cx = 0, cy = 0;
var picture = $('#picture');
var displayedImg = {
width: picture.width(),
height: picture.height()
};
var cw = displayedImg.width, ch = displayedImg.height
Context.rotate(degree * Math.PI / 180);
Context.drawImage(img, cx, cy, cw, ch);
}
}
function showImg(imgFile) {
if (!imgFile.type.match(/image.*/))
return;
var img = document.createElement("img"); // creat img object
img.id = "pic"; //I need set some id
img.src = imgFile; // my picture representing by src
document.getElementById('image_for_crop').appendChild(img); //my image for crop
}
How can I change the canvas element into an img src image in this script? (There may be some bugs in this script.)
canvas.toDataURL() will provide you a data url which can be used as source:
var image = new Image();
image.id = "pic";
image.src = canvas.toDataURL();
document.getElementById('image_for_crop').appendChild(image);
Complete example
Here's a complete example with some random lines. The black-bordered image is generated on a <canvas>, whereas the blue-bordered image is a copy in a <img>, filled with the <canvas>'s data url.
// This is just image generation, skip to DATAURL: below
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d");
// Just some example drawings
var gradient = ctx.createLinearGradient(0, 0, 200, 100);
gradient.addColorStop("0", "#ff0000");
gradient.addColorStop("0.5" ,"#00a0ff");
gradient.addColorStop("1.0", "#f0bf00");
ctx.beginPath();
ctx.moveTo(0, 0);
for (let i = 0; i < 30; ++i) {
ctx.lineTo(Math.random() * 200, Math.random() * 100);
}
ctx.strokeStyle = gradient;
ctx.stroke();
// DATAURL: Actual image generation via data url
var target = new Image();
target.src = canvas.toDataURL();
document.getElementById('result').appendChild(target);
canvas { border: 1px solid black; }
img { border: 1px solid blue; }
body { display: flex; }
div + div {margin-left: 1ex; }
<div>
<p>Original:</p>
<canvas id="canvas" width=200 height=100></canvas>
</div>
<div id="result">
<p>Result via <img>:</p>
</div>
See also:
MDN: canvas.toDataURL() documentation
Do this. Add this to the bottom of your doc just before you close the body tag.
<script>
function canvasToImg() {
var canvas = document.getElementById("yourCanvasID");
var ctx=canvas.getContext("2d");
//draw a red box
ctx.fillStyle="#FF0000";
ctx.fillRect(10,10,30,30);
var url = canvas.toDataURL();
var newImg = document.createElement("img"); // create img tag
newImg.src = url;
document.body.appendChild(newImg); // add to end of your document
}
canvasToImg(); //execute the function
</script>
Of course somewhere in your doc you need the canvas tag that it will grab.
<canvas id="yourCanvasID" />
I´ve found two problems with your Fiddle, one of the problems is first in Zeta´s answer.
the method is not toDataUrl(); is toDataURL(); and you forgot to store the canvas in your variable.
So the Fiddle now works fine http://jsfiddle.net/gfyWK/12/
I hope this helps!
canvas.toDataURL is not working if the original image URL (either relative or absolute) does not belong to the same domain as the web page. Tested from a bookmarklet and a simple javascript in the web page containing the images.
Have a look to David Walsh working example. Put the html and images on your own web server, switch original image to relative or absolute URL, change to an external image URL. Only the first two cases are working.
Corrected the Fiddle - updated shows the Image duplicated into the Canvas...
And right click can be saved as a .PNG
http://jsfiddle.net/gfyWK/67/
<div style="text-align:center">
<img src="http://imgon.net/di-M7Z9.jpg" id="picture" style="display:none;" />
<br />
<div id="for_jcrop">here the image should apear</div>
<canvas id="rotate" style="border:5px double black; margin-top:5px; "></canvas>
</div>
Plus the JS on the fiddle page...
Cheers
Si
Currently looking at saving this to File on the server --- ASP.net C# (.aspx web form page) Any advice would be cool....

Categories

Resources