how to load new image and draw it to the canvas? - javascript

i have a image and i draw that image on the canvas. now i want to change the source of the image and again draw the image in the canvas.
i have tried the below code and here is the jsfiddler. canvas's drawing is not changing.... what to do?
HTML
<button onclick="change_2_new_image();">change_image()</button>
<img id="test" src="http://static.clickbd.com/global/classified/item_img/374646_0_original.jpg" alt="error" title="This is an image" />
<canvas id="myCanvas" width="320px" height="275px"><canvas>
JS
var img;
$(function () {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
img = document.getElementById("test");
img.ready = function () {
alert("asasas");
};
ctx.drawImage(img, 0, 0);
});
function change_2_new_image() {
$('#test').attr("src", "http://upload.wikimedia.org/wikipedia/en/9/9a/Grameenphone_Logo.png");
img = document.getElementById("test");
ctx.drawImage(img, 0, 0);
}

Your issue is with variable scope. You can't access ctx from the function.
function change_2_new_image() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
$('#test').attr("src", "http://upload.wikimedia.org/wikipedia/en/9/9a/Grameenphone_Logo.png");
img = document.getElementById("test");
ctx.drawImage(img, 0, 0);
ctx.render()
}
The above should now work.

ctx is defined inside of your closure and not defined in change_2_new_image() that's why the error message ReferenceError: ctx is not defined is popping up in the console. After fixing that, you may also notice that the image at times, hasn't yet loaded. use jQuery's on('load', ... ) event. for more info, you can have a look at this thread: jQuery event for images loaded
Hope that helps!

Related

How to capture what is visible through a div?

Suppose I have an image and a div whose position is absolute and is above that image (z-index of div more than z-index of image).Something like this :
I want to take screenshot of what is visible through the div using JavaScript. At first I thought of changing the div to a canvas and then I wrote this code:
<div class="utility-btn">
<button class="enquiry-btn" onclick="openEnquiry()">?</button>
</div>
<div id="enquiry">
<button id="close" onclick="closeEnquiry()">X</button>
<div class="cover">
<canvas id="capture"></canvas>
<button class="btn" onclick="takeScreenshot()">
Click to enquiry
</button>
</div>
</div>
Function to take screenshot:
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
backCtx.drawImage(canvas, 0, 0);
ctx.drawImage(backCanvas, 0, 0);
var dataURL = backCanvas.toDataURL();
console.log(dataURL);
}
But the image of dataURL was not what I expected it was just a blank image:
How can I implement this feature. How can I do it without using any external library?
There are two problems:
#1
If we look at your bit of code responsible for actually taking the screenshot
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
backCtx.drawImage(canvas, 0, 0);
ctx.drawImage(backCanvas, 0, 0);
var dataURL = backCanvas.toDataURL();
console.log(dataURL);
}
we can see that canvas is the element you want to have the screenshot taken onto. Later on you're creating an empty new canvas backCanvas and make it the size of the first canvas. Afterwards you're drawing the empty first canvas on the second and finally the empty second canvas back to the first.
So that does not make too much sense.
Instead you need to take the actual canvas generated by threeJS. These lines of your code append a <canvas> element to the container <div>, threeJS is using:
const container = document.getElementById('container');
container.appendChild(renderer.domElement);
We can reference it using:
document.getElementById("container").children[0]
#2
As threeJS uses WebGL to draw stuff, it's rendering context is not the regular and for performance reasons the browser is clearing the drawing buffer after something has been drawn onto - so your screenshot would come up empty all the time. There is an option you need to pass to the THREE.WebGLRenderer constructor to keep the drawingbuffer called preserveDrawingBuffer.
So change this line:
renderer = new THREE.WebGLRenderer();
to this
renderer = new THREE.WebGLRenderer({preserveDrawingBuffer: true});
and your screenshot function to this:
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
ctx.drawImage(document.getElementById("container").children[0], 0, 0);
var dataURL = canvas.toDataURL();
console.log(dataURL);
}

html5-canvas: Conversion of Image file to DataURL throws Uncaught TypeError

I'm trying to get the Base64/Data URL of a chosen image file in Javascript. The user basically selects an image via the File Input control and the Data URL is generated. However, I get this error:
Uncaught TypeError: Failed to execute 'drawImage' on
'CanvasRenderingContext2D': The provided value is not of type
'(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or
ImageBitmap)'
HTML:
<body>
<form id="form1">
<div>
<input type="file" id="imageinput" onchange="testit(event)" />
<canvas width="300" height="300" id="mycanvas" style="display: none;"></canvas>
</div>
</form>
</body>
Javascript:
function testit(event) {
var myImage = URL.createObjectURL(event.target.files[0]);
var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
ctx.drawImage(myImage, 0, 0);
var mydataURL = myCanvas.toDataURL('image/jpg');
alert(mydataURL);
}
Why isn't this code working, guys?
You can not draw an image from url directly to canvas. You have to create a image element/object to do that.
var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img, 0, 0);
alert(myCanvas.toDataURL('image/jpeg'));
};
img.src = URL.createObjectURL(event.target.files[0]);
Here we have created a image object and set the src to user selected image url. After the image is loaded we are adding it to the canvas.
EDIT:
Here we have one more problem. Whatever the image size is, you will always get 300x300 cropped dataurl of the image because of the static canvas width and height. So we can set the width and height to the canvas dynamically after the image loaded. We can use console.log() instead of alert() so that you can open and see the image from your console in your browser itself.
myCanvas.width = img.width;
myCanvas.height = img.height;
Here is the final code:
var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
var img = new Image();
img.onload = function(){
myCanvas.width = img.width;
myCanvas.height = img.height;
ctx.drawImage(img, 0, 0);
console.log(myCanvas.toDataURL('image/jpeg'));
};
img.src = URL.createObjectURL(event.target.files[0]);
Here is the fiddle (i have made the canvas visible so that you can see the whole image and width and height change in canvas):
UPDATE:
As #Kaiido mentioned, It will produce PNG image since the 'image/jpg' is not the mimetype. 'image/jpeg' is the mimetype for both JPG and JPEG images.
Updated Fiddle:
http://jsfiddle.net/k7moorthi/r8soo95p/4/
You're trying to draw an object URL to the canvas. you need to create an image in memory first
http://jsfiddle.net/zmtu6t6c/4/
var myImageUrl = URL.createObjectURL(event.target.files[0]);
var myImage = new Image();
myImage.src = myImageUrl;
myImage.onload = function(){
... then do the canvas stuff
}

Save Canvas image on Ipad

The webpage is being run on Safari on an iPad.
I have a canvas with the id "canvas1div". I would like to be able to receive this canvas as an image either by email or directly into the photo library.
Via Photo Library
With regards to the photo library, I found this question
Save canvas image on local mobile storage for IOS/Android
This is the function that I would like to call to save the image
function saveimage() {
window.canvas2ImagePlugin.saveImageDataToLibrary(
document.getElementById('canvas1div')
);
}
I don't know how to manually add the plug in to javascript so any advice here would be greatly appreciated.
Email
Again I don't know how to convert the canvas to an image and email it.
Thank you for your help
Don't know if this helps you but here you can find download but email send from JavaScript with email cannot be done:
Example with download file below http://jsfiddle.net/oa2s5eu7/1/
Javscript:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0,0,150,75);
// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
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;
}
document.getElementById('mydownload').onclick= function(){
var image = convertCanvasToImage(document.getElementById("myCanvas"));
var anchor = document.createElement('a');
console.log(anchor);
anchor.setAttribute('href', image.src);
anchor.setAttribute('download', 'image.png');
anchor.click();
}
document.getElementById('sendEmail').onclick= function(){
var image = convertCanvasToImage(document.getElementById("myCanvas"));
window.open('mailto:test#example.com?subject=subject&body=you cann send only txt from javscript in email ', '_blank');
}
Html:
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<button id='mydownload'>Download Image</button>
<button id='sendEmail'>Send Email</button>

Javascript - image displaying over text

The code runs with no bugs, but a problem I am having is because the ".onLoad" function makes it display after the text has already been displayed on the screen. The problem I am facing is that I would like if the text (Loading graphics and loading variables) displayed over the image.
The code is here:
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml1-transitional.dtd">
<html>
<body>
<canvas id="ctx" width="800" height="500" style="border:1px solid #d3d3d3;"></canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById('ctx');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function(){
context.drawImage(imageObj,0,0);
};
imageObj.src = 'img/startscreen.jpg';
ctx.fillText('Loading variables.',50,50);
character=new Object();
character.hp=1;
character.name=null;
ctx.fillText('Loading graphics..',50,100);
</script>
</body>
</html>
I would layer the background image on its own canvas positioned behind the text layer. Then you can clear and update the text layer without having to re-draw the background image.
#background,#overlay {
position: absolute;
}
<canvas id="background"></canvas>
<canvas id="overlay"></canvas>
var can = document.getElementById('overlay'),
bg_can = document.getElementById('background'),
height = can.height = bg_can.height = 500,
width = can.width = bg_can.width = 500,
ctx = can.getContext('2d'),
bctx = bg_can.getContext('2d');
var img = new Image();
img.src = ' ... ';
img.onload = init;
function init() {
// draw the background
bctx.drawImage(this, 0, 0);
// draw your initial text
updateText('hello world');
// other stuff that is going to take time
updateText('done');
}
function updateText(msg) {
ctx.clearRect(0, 0, width, height);
ctx.fillText(msg, 50, 100);
}
This isn't very well thought out (my code example) for re-use purposes.. but I don't know much about your other needs :) hope this helps.
If you want to overlay String on image, why don you use image as backGround imange and place text over it??
Css
try in css
#ctx{
background-image:url('img/startscreen.jpg');}
remove image source in script or insert css in script itself
Css in scripts
ctx.style.backgroundImage=url('img/startscreen.jpg');
I called the function for the text to be displayed after the background has:
imageObj.src = 'img/startscreen.jpg';
imageObj.onload = function(){
context.drawImage(imageObj,0,0);
init()
};
function init(){
ctx.fillText('Loading variables.',50,50);
character=new Object();
character.hp=1;
character.name=null;
ctx.fillText('Loading graphics..',50,100);
}

HTML5 Canvas no method 'toDataURL'

My Code is like this
<html>
<head>
</head>
<body>
<canvas id="myCanvas" width="578" height="200" style="display:none;"></canvas>
<img id="canvasImg" onclick="myFunction()" alt="Right click to save me!">
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
function myFunction() {
var c = document.getElementsByTagName("canvas");
// save canvas image as data url (png format by default)
var dataURL = c.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
document.getElementById('canvasImg').src = dataURL;
}
</script>
</body>
</html>
When i click on canvasImg its throwing an error
Uncaught TypeError: Object #<NodeList> has no method 'toDataURL'
I have made a fiddle here
Can any one point out whats going wrong?
DEMO
document.getElementsByTagName returns array of elements objects, and no array objects have method toDataUrl
instead of this
var c = document.getElementsByTagName("canvas");
use
var c = document.getElementsByTagName("canvas")[0];
function myFunction() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var img = document.getElementById("canvasImg");
context.drawImage(img, 0, 0);
}

Categories

Resources