I am trying to invert the color of an image. Now the image loads ok, but when I try to call getImageData and putImageData back onto the canvas. The canvas is simply blank. Then I printed out all imageData, it appears like that it is always 0 for some reason. I am seriously troubled by this. Please help and thx in advance!
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "hand.jpg";
img.onload = function() {
ctx.drawImage(img, 10, 10,50,50);
}
var imgData = ctx.getImageData(10,10,50,50);
console.log(imgData.data.toString()); //return 0's
for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,100,100);
}
You need to wait for the image to load
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "hand.jpg";
//================================================================
// this event will only get called after you have returned from this function
img.onload = function() {
ctx.drawImage(img, 10, 10,50,50);
}
//================================================================
// The image has not loaded at this point
// the following code will always be working on an empty canvas
var imgData = ctx.getImageData(10,10,50,50);
console.log(imgData.data.toString()); //return 0's
for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,100,100);
//================================================================
// onload will fire after this point
}
To fix
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "hand.jpg";
img.onload = function() {
ctx.drawImage(img, 10, 10,50,50);
var imgData = ctx.getImageData(10,10,50,50);
for (var i=0;i<imgData.data.length;i+=4){
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,100,100);
}
}
BTW you can invert the image colours with
ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white"
ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.globalCompositeOperation = "source-over"; // restore default
Related
I have a problem.
I need to capture a iamgem from my webcam, and work in canvas with this image.
my code is:
Webcam.set({
width: 640,
height: 480,
image_format: 'jpeg',
jpeg_quality: 90
});
Webcam.attach('#my_camera');
function take_snapshot() {
Webcam.snap(function (data_uri) {
var canvas = document.getElementById("results");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.drawImage(data_uri, 0, 0);
});
}
This is what I try and I know it is wrong.
So what I need to do to fix this?
drawImage() cannot draw data-uris directly so they have be converted to an image element first:
Webcam.snap(function (data_uri) {
var canvas = document.getElementById("results");
var ctx = canvas.getContext("2d");
var img = new Image(); // create an image element for data-uri
img.onload = function() { // add async handler
ctx.drawImage(this, 0, 0); // when loaded, draw image (this)
// goto next step from here as this block is async
};
img.src = data_uri; // set data-uri as source
});
I'm trying to create an 'eraser' effect in Canvas, but using an SVG image as a custom shape for the eraser.
So I can draw my SVG image to canvas, and use globalCompositeOperation='destination-out' to create a masking effect.
It works great in IE, Safari, and Chrome. But it utterly fails in Firefox.
function init() {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function () {
ctx.beginPath();
ctx.drawImage(img, 0, 0);
ctx.closePath();
ctx.globalCompositeOperation = 'destination-out';
}
img.src = "http://www.evanburke.com/FROST.png";
var svg = new Image;
svg.src = "http://www.evanburke.com/luf.svg";
function drawPoint(pointX,pointY){
ctx.drawImage(svg,pointX,pointY);
}
canvas.addEventListener('mousemove',function(e){
drawPoint(e.clientX,e.clientY);
},false);
}
<body onload="javascript:init();">
<div>
<canvas id="c" width="400" height="400"></canvas>
</div>
</body>
That's indeed a bug, and as advised by #RobertLongson, you should raise a bug in Mozilla's Buzilla.
But first, you should clean up your code : ctx.beginPath() is useless. and ctx.closePath() doesn't do what yo think it does.
If you want a workaround for this issue, you could first draw the svg image onto a canvas, then use this canvas as the eraser :
(function init() {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var svgCan;
var img = document.createElement('IMG');
img.onload = function() {
ctx.drawImage(this, 0, 0);
ctx.globalCompositeOperation = 'destination-out';
}
img.src = "http://www.evanburke.com/FROST.png";
var svg = new Image();
svg.src = "http://www.evanburke.com/luf.svg";
svg.onload = function() {
// create a canvas
svgCan = canvas.cloneNode();
svgCan.width = this.width;
svgCan.height = this.height;
// draw the svg on this new canvas
svgCan.getContext('2d').drawImage(svg, 0, 0);
}
function drawPoint(pointX, pointY) {
// this is now a pixel image that will work with gCO
ctx.drawImage(svgCan, pointX, pointY);
}
canvas.addEventListener('mousemove', function(e) {
drawPoint(e.clientX, e.clientY);
}, false);
})()
<div>
<canvas id="c" width="400" height="400"></canvas>
</div>
I am a new user and cannot comment on this post: dragging and resizing an image on html5 canvas regarding drag and drop/resize image with anchors...
could someone please clarify how to apply the resize/drag/anchors to an uploaded image rather than a pre-loaded image please?
I have had a go but its killing me..
uploader html:
<input type="file" id="imageLoader" name="imageLoader" />
uploader js:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, 200, 140);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
fiddle
your code is written to handle the global var img.
When you load a new image, a new local img var is created, which you only draw on the context.
What you need is to have the new image replace the old one.
So just change, in your file loader :
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
img = new Image(); // not 'var img=...'
img.onload = function () {
draw(true,true); // just update your app
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
it workd, as you can see here :
http://jsfiddle.net/LAS8L/108/
I am trying to put an image on a canvas. I read the following tutorial
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
and tried to do something similar to it
my canvas is <canvas id="canvas" width="400" height="400"></canvas>
and I have created the function
function putImage(){
var img = new Image();
img.src = "./path.png";
var ctx = document.getElementById('canvas').getContext('2d');
ctx.drawImage(img,8,8);
}
but the image is not appearing on the canvas.
I have printed the image path and it is correct, so I was able to eliminate this issue.
any suggestions?
thanks
According to the tutorial, you're supposed to wrap your ctx.drawImage() inside img.onload like so
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = '/files/4531/backdrop.png';
}
I hope this helps.
If you don't like to use Promise or onload you can also use EventListener:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.addEventListener('load', function(){
ctx.drawImage(img, 0, 0);
});
img.src = '/files/4531/backdrop.png';
}
To add to Hass's answer: If you don't like the onload approach, you can await a Promise, like so:
async function draw() {
let ctx = document.getElementById("canvas").getContext('2d');
let url = "https://example.com/image.png";
let img = new Image();
await new Promise(r => img.onload=r, img.src=url);
ctx.drawImage(img, 0, 0);
}
I have a problem when I use drawImage function to draw an image inside an html5 canvas ;used with a code Sencha Touch 2 images look blu and they don't have height quality this is the code:
//We've added a third and final item to our tab panel - scroll down to see it
var index=0;
Ext.application({
name: 'Sencha',
launch: function() {
var panel = Ext.create("Ext.Panel", {
fullscreen: true,
items: [
{
title: 'Home',
iconCls: 'home',
cls: 'home',
width: '533px',
listeners: {
painted: function() {
var a={Source:'images/2.tiff',Titre:'T1',Description:'D1'};
var b={Source:'images/Im2.jpg',Titre:'T1',Description:'D1'};
var c={Source:'images/Im3.jpg',Titre:'T1',Description:'D1'};
var d={Source:'images/Im4.jpg',Titre:'T1',Description:'D1'};
var e={Source:'images/Im5.jpg',Titre:'T1',Description:'D1'};
var f={Source:'images/Im6.jpg',Titre:'T1',Description:'D1'};
var img = new Image();
var img1 = new Image();
var img2 = new Image();
img.src = "images/Im1.jpg";
img1.src = "images/Im2.jpg";
img2.src = "images/Im3.jpg";
var ImageP = new Image();
//********************
var x,y,Dim_Image,espacement;
Dim_Image=50;
espacement=30;
var Presentation=new Array();
Presentation[0]=a;
Presentation[1]=b;
Presentation[2]=c;
Presentation[3]=d;
Presentation[4]=e;
Presentation[5]=f;
//********************
//°°°°°°°°°°°°°°°°°°°°°°
/* Ici on teste le tableau*/
var testImage = new Array();
//cw-(i*espacement),i*espacement,Dim_Image,Dim_Image);
var j=0;
for(i=index;i<index+3;i++)
{
testImage[i]= new Image();
testImage[i].src=Presentation[i].Source;
testImage[i].onload = function()
{
context.drawImage(testImage[j],cw-80-(j*espacement),20+j*espacement,Dim_Image,Dim_Image);
j++;
}
}index = index +1;
var img = new Image();
var canvas = document.getElementById('mycanvas');
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
//Event================================================================
canvas.addEventListener("mousedown" ,function(event){
testImage = new Array();
context.clearRect(0,0,300,300); // clear canvas
var j=0;var inf =index;var ss;
for(i=index;i<index+3;i++)
{
testImage[i-index]= new Image();
testImage[i-index].src=Presentation[i].Source;
if( i == index+2)
{alert("index +3");
testImage[i-index].onload = function()
{context.globalAlpha=1;
context.drawImage(testImage[j],cw-80-(j*espacement),20+j*espacement,Dim_Image,Dim_Image);
j++;
}
}
else{
testImage[i-index].onload = function()
{context.globalAlpha=0.5;
context.drawImage(testImage[j],cw-80-(j*espacement),20+j*espacement,Dim_Image,Dim_Image);
j++;
}
}
}
index=index+1;
context.stroke();
},false);
context.strokeStyle = 'black';
context.stroke();
//};
},
scope: this
},
html: [
' <canvas id="mycanvas" style="background-color:grey; width:100%; height:100%;">no canvas support</canvas>'
]
} //this is the new item
]
});
}
});
What exactly you are trying to achieve?
Perhaps the problem is related to the drawImage method type you are using
Have a look at this link on the usage how to use, and what exactly the parameters that you added means.
Problem may be aspect ratio , width , height calculation from your side.
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage