Save image from html5 canvas - javascript

$("#fileinput").change(function (e) {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function () {
ctx.drawImage(img, 0, 0, img.width, img.height,
0, 0, canvas.width, canvas.height);}
});
So far it is working good. Now I'm trying send the image to server as form data via ajax-
var fd = new FormData();
var canvasData = canvas.toDataURL("image/png");
//I tried
var canvasData = canvas.getImageData();
//Gives Uncaught TypeError: canvas.getImageData is not a function(…)
fd.append("InsidePhoto", canvasData);
But it sends nothing. Ajax code has been tested and works fine. I think I can not get the image from canvas. Any idea?

Here's a worked example. Hard to tell quite where your problem lies with the code you've omitted. In the second snippet for instance, we can't tell if canvas is valid.
php code: (postExample.php)
<?php
//postExample.php
printf("<img src='%s'/>", $_POST['InsidePhoto']);
?>
html code
<!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
function ajaxPostFormData(url, formData, onSuccess, onError)
{
var ajax = new XMLHttpRequest();
ajax.onload = function(){onSuccess(this);}
ajax.onerror = function(){onError(this);}
ajax.open("POST",url,true);
ajax.send(formData);
}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('imgInput').addEventListener('change', onFileInputChanged, false);
}
function onFileInputChanged(evt)
{
var can = byId('preview'), ctx = can.getContext('2d');
var img = new Image();
img.onload = function()
{
can.width = img.width;
can.height = img.height;
ctx.drawImage(img,0,0);
var fd = new FormData();
var canvasData = can.toDataURL("image/png");
fd.append("InsidePhoto", canvasData);
ajaxPostFormData('postExample.php', fd, onSuccess, onError)
}
var dataSrc = URL.createObjectURL(this.files[0]);
img.src = dataSrc;
function onSuccess(ajax)
{
console.log(ajax.response);
var div = newEl('div');
div.innerHTML = ajax.response;
document.body.appendChild( div.childNodes[0] );
}
function onError(ajax)
{
console.log(ajax.response);
}
}
</script>
<style>
</style>
</head>
<body>
<input type='file' id='imgInput'/>
<canvas id='preview'></canvas>
</body>
</html>

You need to use CanvasRenderingContext2D's getImageData(x, y, width, height) function to get the canvas' image data not the canvas element's.
The first 2 values are the starting positions, set these to 0 to start from the top-left edge.
The second 2 values are the width and height of the area, so set these to canvas.width and canvas.height respectively.

Related

Base64 encoding an image alerts correct, response is nil

I'm trying to encode an image in Base64 from a URL.
function getBase64Image(url) {
var img = new Image(),
response = '';
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL('image/png');
response = dataURL;
alert(response);
};
img.src = url;
return response;
}
The alert() works fine but the response is nil:
You can see in the console in the screenshot if I log the response like so (it's done twice in the screenshot) it returns nothing:
console.log(getBase64Image('<%= asset_path "test.jpg" %>'));
Obviously we can read the image because the alert has the encoding. What am I missing?
Update
Relevant JSFiddle: https://jsfiddle.net/guxzxq20/3/
Approach: Canvas
Load the image into an Image-Object, paint it to a non-tainted canvas and convert the canvas back to a dataURL.
function convertImgToDataURLviaCanvas(url, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
canvas = null;
};
img.src = url;
}
call method
convertImgToDataURLviaCanvas('http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo_2013_Google.png',function(response){
alert(response)
});
I believe you are returning the empty response object that you have created, because the response object inside the onLoad() function is not accessing the outside response.
Try changing your code to calling a callback once the onload() function reaches its end, and using that callback to alert.
Something like:
function getBase(url, callback) {
// ... code
img.onload = function () {
// ... code
callback(response);
}
}
This was a very raw example.

Convert image into base64string in JQuery

I am working on VS2015 cordova app .I want to send an base 64 string of an image to another server . I have a problem when i get image from gallery and corverting it into base64string . I got the base64string successfully but when i dispalayed it I always get black image . here is my code :
function onPhotoURISuccess(imageURI) {
var largeImage = document.getElementById('smallImage');
largeImage.style.display = 'block';
largeImage.src = imageURI;
basestrg = encodeImageUri(imageURI);
}
function getPhoto(source) {
navigator.camera.getPicture(onPhotoURISuccess, onFail, {
destinationType: Camera.DestinationType.NATIVE_URI, mediaType: Camera.MediaType.Photo,
sourceType: source
});
}
function encodeImageUri(imageUri) {
var c = document.createElement('canvas');
var ctx = c.getContext("2d");
var img = new Image();
img.onload = function () {
c.width = this.width;
c.height = this.height;
ctx.drawImage(img, 0, 0);
};
img.src = imageUri;
var dataURL = c.toDataURL("image/jpeg");
return dataURL;
}
Please advice .
This is beside the context but may help you.
You can upload the image directly from your html5 form.
<form enctype="multipart/form-data" action="upload.php" method="post">
<input name="userImage" type="file" accept="image/*;capture=camera">
<button type="submit">Submit</button>
</form>
Get the image data in upload.php file and save as image. In PHP use $_FILES array and for C# use HttpContext to save the image.Ref: Using form input to access camera and immediately upload photos using web app
Your image isn't loaded by the time you try to get the data url.
function encodeImageUri(imageUri, callback) {
var c = document.createElement('canvas');
var ctx = c.getContext("2d");
var img = new Image();
img.onload = function () {
c.width = this.width;
c.height = this.height;
ctx.drawImage(img, 0, 0);
var dataURL = c.toDataURL("image/jpeg");
callback(dataURL);
};
img.src = imageUri;
}
Then change the other function to pass a callback
function onPhotoURISuccess(imageURI) {
var largeImage = document.getElementById('smallImage');
largeImage.style.display = 'block';
largeImage.src = imageURI;
encodeImageUri(imageURI, function(datauri){
basestrg = datauri;
//Now send the string to the server here.
});
}

JavaScript runtime error: Unspecified error

My requirement is to return data URL. But, when I run the application, there is an run-time error:
JavaScript runtime error: Unspecified error.
Here is the code that I have used. Temp path is the path where is location of image is.
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var img = new Image();
img.src = "#tempPath";
context.drawImage(img, 40, 40);
var dataURL = canvas.toDataURL("image/jpeg");
alert(dataURL);'
Try following code, It worked for me:
<body>
<canvas id="myCanvas"></canvas>
<img id="profileImg" alt=""/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
drawImg();
});
function drawImg() {
try {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var img = new Image();
img.src = $('#profileImg');
context.drawImage(img, 40, 40);
var dataURL = canvas.toDataURL("image/jpeg");
alert(dataURL);
} catch (e) {
if (e.name == "NS_ERROR_NOT_AVAILABLE") {
// This is a bug in Firefox. The easiest fix is to simply keep trying until the error goes away,
//since no event fires at the correct time.
// Wait before trying again; you can change the length of this delay.
setTimeout(drawImg, 100);
} else {
throw e;
}
}
}
</script>
</body>
Works well with IE as well. Hope this helps.

Displaying one canvas to another

I have a problem displaying one canvas to another. I do everything according to this solution
<script>
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src = 'icon.jpg';
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
destin_ctx.drawImage(source, 0, 0);
</script>
Well, first canvas element displays picture correctly, but whatever I do, the second canvas does not want to display a picture.
<script>
function init()
{
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'arun.jpg';
}
</script>
</head>
<body onload="init();">
<canvas id="hiddenCanvas" />
<canvas id="visibleCanvas" />
Your code is not working because you are trying to access canvas element before it is loaded to dom
The way you've currently structured the code, img.onload is executed after the destin_ctx.drawImage line. That means that your program flow currently looks something like this:
Image is told to start loading
Destination canvas is drawn using (currently blank) source canvas
Image finishes loading
Image's onload executes, causing the source canvas to be drawn to. The destination canvas is NOT updated, because the destin_ctx.drawImage operation is a one-time copy.
What you need to do is move the destin_ctw.drawImage call to a place in the execution flow where you know the source canvas will definitely contain the appropriate contents. In this simple case, moving it to inside the image's onload would work.
Here's a full (but simplified) HTML file that works for me in Chromium, with a changed image url:
<script>
function load() {
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'ship360_32.png';
}
</script>
<body onload="load()">
<canvas id="hiddenCanvas"></canvas>
<canvas id="visibleCanvas"></canvas>
</body>
You are trying to draw the image from source before the image is loaded and the source even have the image.
Move the last draw operation inside the onload handler. Also remember to set the size for destination canvas:
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destination.width = source.width;
destination.height = source.height;
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'icon.jpg';

Loading Image into document.body Background

I'm attempting to pull an image (in this case, /camera/frame, which is a known-good JPG), and load it as the background of my document.body.
Here's my code thus far:
var backgroundImage = new Image();
backgroundImage.onload = function ()
{
console.log("onload");
document.body.style.backgroundImage = this.src;
};
backgroundImage.src = 'camera/frame';
"onload" prints as expected, and this.src prints out the full URL to /camera/frame, however document.body.style.backgroundImage remains "".
I believe you may be missing two things.
var path = 'path/to/image.jpg';
document.body.style.background='url('+path+')';
Canvas 2D to the rescue!
var backgroundImage = new Image();
backgroundImage.onload = function ()
{
var canvas = document.getElementById('canvas');
canvas.width = this.width;
canvas.height = this.height;
var canvasContext = canvas.getContext('2d');
canvasContext.drawImage(this, 0, 0, this.width, this.height);
};
backgroundImage.src = 'camera/frame';
backgroundImage.width = $(window).width();
backgroundImage.height = $(window).height();
Loads the image in the background, then draws it into the canvas seamlessly!

Categories

Resources