Save a html canvas image - html

I know there is probably an answer already to this question but I haven't been able to find it yet and there is a deadline on my project.
So I have made an html5 canvas and I would like to be able to do two things with one(or more) buttons.
I would like the user to be able to save what he has just done by clicking on the save button and ideally I would like the image to be downloaded (as opposed to having to right click and "Save image as". This is what I have been able to do so far).
I would also like the image to be saved (maybe to a database? or a server? I don't know how it works) so that a part of the drawing (or all of it, depending on the difficulty of the code) that has been done before is used the next time someone else logs on (not necessarily the same person with the same IP). Is this possible?
I am very new to code and self teaching myself so any extra comments on the code to help me understand would be extra-appreciated.

Regarding the first task, you can export the canvas content to an image with toDataUrl method supported by the canvas object.
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d"); // Get the context for the canvas.
var myImage = canvas.toDataURL("image/png"); // Get the data as an image.
}
var image = document.getElementById("image"); // Get the image object.
image.src = myImage;
As regarding the second task, after you saved the canvas to an image you can upload the resulted image into the database by using an ajax call. Here is a simple example for how to use it:
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
document.getElementById("response").innerHTML = res;
}
});
For a full example see these articles:
http://net.tutsplus.com/tutorials/javascript-ajax/uploading-files-with-ajax/
http://coursesweb.net/ajax/upload-images

You would probably need to use JavaScript and maybe PHP. I am not proficient in both of those so I can't help you, but you should look up tutorials on how to make a database on your website.

i think you might be interested to have a look on the html5 file api :
http://updates.html5rocks.com/2012/08/Integrating-input-type-file-with-the-Filesystem-API
It would allow you to deal with your issue with no server-side code.
(Rq : this will not solve all your issues.)

Related

Limit the size (bytewise) of an image loaded with the <img> tag

The initial problem: I want that the users of my future webserver can use an avatar.
The initial solutions (and their problems)
Let the user upload his own image and save it
the pro here is that I might limit from the start the size of the image
the problem, instead, even if no one seems to care too much, is legal: not sure how it works in other countries, but here you might be considered liable for what you store on your hdd, in some cases (which I won't list, but that you might guess). This means that if someone uploads an illicit image as his avatar on your server and then this is reported to the authorities, you might find yourself in some kind of trouble, which, depending from the examining magistrate, might easily lead to the server going under requisition for months, for "further investigations".
And here we came with the second idea: let the user define and save a link to an image, for his avatar
pro: legally safe
cons: what if the user defines a link to a 100MB image, which then all the users might be forced to download to see the page?
So the question is: is there a way to "say" to the browser that when it sees:
<img src='http://external.jpg' ...>
external.jpg size is supposed to be limited to, say, 100KB? And to drop the loading of it, if it goes over that size?
With this function you can get the file size and determine what to do from there. Also you can use an API like Clarifai to check for illicit content if you want to store it on your HDD.
function get_filesize(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("HEAD", url, true); // Notice "HEAD" instead of "GET",
// to get only the header
xhr.onreadystatechange = function() {
if (this.readyState == this.DONE) {
callback(parseInt(xhr.getResponseHeader("Content-Length")));
}
};
xhr.send();
}
get_filesize("URLHERE", function(size) {
alert("The size of foo.exe is: " + size + " bytes.");
});
Source: Ajax - Get size of file before downloading

display only a specific content in AS3 code using webStage View

I'd like to display, in my app, only a part of a web page.
On this website, I'd like to display, in my app, only the div id "MovieCart".
What should I write in my as3 code in order to do so ?
For now, I have this line :
webView.loadURL("http://www.cinecity.nc/Cinecity/Film/40565");
But, of course, it's displaying the fullwebpage.
EDIT
So, I've tried this :
webView.addEventListener(Event.COMPLETE,onComplete);
var res : String = ExternalInterface.call("function(){return document.getElementById('movieCart').outerHTML}");
var urlOfMovie: URLRequest = new URLRequest("http://www.cinecity.nc/Cinecity/Film/40567");
var loaderMovie:URLLoader = new URLLoader();
loaderMovie.load(urlOfMovie);
webView.loadString(res);
But, as it's an AIR app, ExternalInterface.call can't be call. Any idea ?
Here is one easy way you can accomplish this:
//First, load the full page as you're currently doing:
webView.addEventListener(Event.COMPLETE, webLoadComplete); //listen for when the load is finished
webView.loadURL("http://www.cinecity.nc/Cinecity/Film/40565");
//runs when the load finishes
function webLoadComplete(e:Event):void {
webView.removeEventListener(Event.COMPLETE, webLoadComplete); //stop listening
//second, invoke the following Javascript on the page which assigns the `MovieCart` element as the html for the whole document body
webView.loadURL("javascript:document.body.innerHTML = document.getElementById("MovieCart").outerHTML");
}
Disclaimer:
Keep in mind that scrapping content from websites is generally frowned upon and you may be infringing on peoples work/copyrights by doing so.

AS3 POST png to PHP

Have read many similar but no solutions: I'm trying to do something (that i think is) really simple,
Take a photo from gallery or camera - and POST this to a URL. No saving / returning to application. The PNG is just used by the webpage in display and user moves onward.
public function postPicture():void {
PNGEncoder2.level = CompressionLevel.FAST;
var encoder : PNGEncoder2 = PNGEncoder2.encodeAsync(_bitmapData);
encoder.targetFPS = 12;
encoder.addEventListener(Event.COMPLETE, function (e):void {
var png : ByteArray = encoder.png;
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var jpgURLRequest:URLRequest = new URLRequest("https://myurl.com/mypage");
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = png;
navigateToURL(jpgURLRequest, "_blank");
});
}
Also to note, we're getting some odd characters on the end of the URL: C9%90NG
Hunch is that I'm decoding and then not encoding properly before sending i.e. these characters some part of raw image info.
When I test from chrome POST extension with another image, server side stuff works fine so guessing a problem with AS3.
basically its working when I use chrome to browse > my.png and POST it at the page. Am I missing something with the AS3 png encoder? i.e. how to turn that bmpdata into a 'file' rather than an array of bytes.
thankyou
You need to use multipart upload. It's a common situation with a well defined standards for that. You can implement it by yourself but it will take some time and efforts.
What I've used before is the Multipart URLLoader Class provided by Eugene Zatepyakin, one the best Flash guru's out there :)
It's some kind of old but does the job extremely well. You can add variables, files, whatever content you want to your loader and simply submit it. There are examples with the php side of the thing so you can understand what's going on.

Downloading a dynamically generated SVG file from the browser

If I create an image using HTML SVG element, can I then offer this as an SVG file download to the user. For example I may want to load an SVG image, apply some basic transformations to it, add some text, then let the user download the result as a vector image.
Is that possible? I have been doing something similar with Canvas but have been struggling creating a vector image. I wasn't aware that SVG elements were so versatile when I cam across them this morning but if I can do the above it would be great.
Simple solution using a data URI:
var svg_root = document.getElementById('your_svg_root_element_here');
var svg_source = svg_root.outerHTML;
var svg_data_uri = 'data:image/svg+xml;base64,' + btoa(svg_source);
var link = document.getElementById('anchor_element');
link.setAttribute('href', svg_data_uri);
Although it worked, when clicking on the link, the browser stalled for a few seconds.
This seems to be the simplest solution and should be compatible with all modern browsers. However, it has some noticeable overhead. If someone else knows a different solution (maybe using blobs or something similar), please add here as another answer!

How to Copy Contents of One Canvas to Another Canvas Locally

I'd like to copy ALL contents of one canvas and transfer them to another all on the client-side. I would think that I would use the canvas.toDataURL() and context.drawImage() method to implement this but I am running into a few issues.
My solution would be to get Canvas.toDataURL() and store this in an Image object in Javascript, and then use the context.drawImage() method to place it back.
However, I believe the toDataURL method returns a 64 bit encoded tag with "data:image/png;base64," prepended to it. This does not seem to be a valid tag, (I could always use some RegEx to remove this), but is that 64 bit encoded string AFTER the "data:image/png;base64," substring a valid image? Can I say image.src=iVBORw...ASASDAS, and draw this back on the canvas?
I've looked at some related issues:
Display canvas image from one canvas to another canvas using base64
But the solutions don't appear to be correct.
Actually you don't have to create an image at all. drawImage() will accept a Canvas as well as an Image object.
//grab the context from your destination canvas
var destCtx = destinationCanvas.getContext('2d');
//call its drawImage() function passing it the source canvas directly
destCtx.drawImage(sourceCanvas, 0, 0);
Way faster than using an ImageData object or Image element.
Note that sourceCanvas can be a HTMLImageElement, HTMLVideoElement, or a HTMLCanvasElement. As mentioned by Dave in a comment below this answer, you cannot use a canvas drawing context as your source. If you have a canvas drawing context instead of the canvas element it was created from, there is a reference to the original canvas element on the context under context.canvas.
Here is a jsPerf to demonstrate why this is the only right way to clone a canvas: http://jsperf.com/copying-a-canvas-element
#robert-hurst has a cleaner approach.
However, this solution may also be used, in places when you actually want to have a copy of Data Url after copying. For example, when you are building a website that uses lots of image/canvas operations.
// select canvas elements
var sourceCanvas = document.getElementById("some-unique-id");
var destCanvas = document.getElementsByClassName("some-class-selector")[0];
//copy canvas by DataUrl
var sourceImageData = sourceCanvas.toDataURL("image/png");
var destCanvasContext = destCanvas.getContext('2d');
var destinationImage = new Image;
destinationImage.onload = function(){
destCanvasContext.drawImage(destinationImage,0,0);
};
destinationImage.src = sourceImageData;