O'Reilly

JavaScript Canvas Image Conversion

By on  

At last week's Mozilla WebDev Offsite, we all spent half of the last day hacking on our future Mozilla Marketplace app. One mobile app that recently got a lot of attention was Instagram, which sold to Facebook for the bat shit crazy price of one billion dollars. Since I wouldn't mind having a bill in my back account, I decided to create an Instagram-style app (which I'll share with you in the future). This post details how you can convert an image to canvas and convert a canvas back to an image.

Convert an Image to Canvas with JavaScript

To convert an image to canvas, you use a canvas element's context's drawImage method:

// 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;
}

The 0, 0 arguments map to coordinates on the canvas where the image data should be placed.

Convert Canvas to an Image with JavaScript

Assuming modifications to the image have been made, you can easily convert the canvas data to image data with the following snippet:

// Converts canvas to an image
function convertCanvasToImage(canvas) {
	var image = new Image();
	image.src = canvas.toDataURL("image/png");
	return image;
}

The code above magically converts the canvas to a PNG data URI!

Alas, converting an image to canvas and canvas to an image is probably much easier than you think. In future posts, I'll detail how you can apply different image filters to your canvased image. In the mean time, start buying fancy cars and houses with the future billion you'll have!

Track.js Error Reporting

Upcoming Events

Recent Features

  • Designing for Simplicity

    Before we get started, it's worth me spending a brief moment introducing myself to you. My name is Mark (or @integralist if Twitter happens to be your communication tool of choice) and I currently work for BBC News in London England as a principal engineer/tech...

  • 5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • Multiple File Upload Input

    More often than not, I find myself wanting to upload more than one file at a time.  Having to use multiple "file" INPUT elements is annoying, slow, and inefficient.  And if I hate them, I can't imagine how annoyed my users would be.  Luckily Safari, Chrome,...

  • Event Delegation with MooTools

    Events play a huge role in JavaScript. I can't name one website I've created in the past two years that hasn't used JavaScript event handling on some level. Ask yourself: how often do I inject elements into the DOM and not add an...

Discussion

  1. convertCanvasToImage should have a callback parameter, because the data set as image src takes some time to load. So the returned image may be blank. ;o)

    Better handling:

    // Converts canvas to an image
    function convertCanvasToImage(canvas, callback) {
      var image = new Image();
      image.onload = function(){
        callback(image);
      }
      image.src = canvas.toDataURL("image/png");
    }
    
  2. Cool Stuff David! I have been playing with canvas a few months ago and using similar code code to your example I’ve created a javascript image compression tool that works pretty well.

    The cool thing about it is that you can compress images on the client side before uploading :)

    You can check out the demo at http://makeitsolutions.com/labs/jic/

    • Varun

      Checked out your solution, but couldnt get how you ‘compress’ it? All I can see is, you take the image quality between 0 & 1 and use that on toDataURL() and return the resulting object. There isnt any special compress or am i missing something?

  3. I have created a plugin in jquery which will easily convert images to canvas, and let you download the current image lying on canvas.

    Generally outputting canvas to image gives ImageData ( base64 ), i have used a little php script that will give a direct download option to user.

    http://thetutlage.com/post=TUT213

  4. Kevin

    In function convertImageToCanvas(image) where does ‘image’ come from?

    • The image is a reference to an image node within the page.

  5. Ashwini

    I am developing a Phonegap app for Android and in Android, toDataUrl() method is supported in 3.2+ versions. My intention is to get a cropped image in .png or .jpeg format and send that cropped image to server. Please guide me doing this.

  6. roscky

    How can I send a Image to the sever and save it in the sever using php?

    • You’d do an AJAX POST to the server and save the data to file.

  7. Crail

    How can i rotate before convert canvas to image?

  8. Nisanth

    Can i use this to resize images for retina resolution??

  9. amaro

    Hello Guys,

    What should be different if I need to convert from png to canvas and canvas to jpg?

  10. Hi Guys,

    What should be different if I need to convert from png to canvas and canvas to jpg

  11. Worth noting that this could fail if your image isn’t from the same domain. Check out https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image for details on how to safely work past cross-origin canvas tainting.

  12. Anand

    I want to convert div contents in to image and save in a folder ????? any one have idea?…….

  13. Mat

    Great, thanks for the example. It works awesomely.

  14. Aslam

    Hai,

    What is the advantage of converting an image to canvas? Does it decrease the size of picture(or in terms of loading time)…………?

    • No, I think the idea is to convert the image to canvas so you can apply effects to it using javascript.

  15. When I press “snap photo” it takes the photo and it then reloads the page, any thoughts.Code as I have it (on an aspx page with nothing else on it)

    https://gist.github.com/ghirst/7370961

    • César

      same problem in here, did you solve it?

  16. Hi,

    Are you able to convert a Java Script code to jpeg file? I have 6 image banners from the forex company that I am an affiliate with. I have the Landing page URL which I made the tiny URL and the original java script code. I need to convert it to jpeg to upload the image for facebook ad campaign. How do I go about it?

    Are you also able to resize it to 600 pixels wide by 225 pixels tall with high resolution as required by facebook to place ad on their news feed and make sure that the original Java Script Code remain the same so it will track to my campaign ID with the forex company.

    Let me know if you are able to help me. Much appreciated!

    Thanks a lot!
    Mrityunjay

  17. Hi David,

    How does this code behave with IE10/IE11, where I am loading image from other domain, let say I have angular application, I am loading Image via web server call.

    toDataURL() is not working incase of cross domain images, throwing security exception in IE10/IE11. Can you please suggest any solution for this.

    Shravan

  18. You really wrote a nice guide for this effect.

    But for me, as newcomer, I’m would like to ask:
    Why, do they convert the pictures to Canvas elements?

    kind regard

  19. Prasanna

    Hi

    I need to convert Div content to image … Can you guide me how it can be done …. a sample code will help even better ..

    Thanks

  20. Hey ! Thanks for this post !
    By the way, it seems canvas to image is no longer secure, or at least, it have been restricted.

    I try to convert a canvas to a PNG image, and I’ve got : Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

    With further researches, I found this stackoverflow question : http://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror That mention For example, you can no longer use the canvas toBlob(), toDataURL(), or getImageData() methods; doing so will throw a security error.

    Is there a way to go beyond those security errors .. ? Or any fix/solutions to it ?

    Thanks by advance !
    Lucas.

  21. Milind

    The above example i.e for just single image works fine, but need to know how do we achieve for multiple images which are being dynamically fetched from database.
    below is the code snippet

    
    cat_ids is array of image ids and 
    cat_urls has Thumbnail urls of the images.
    
    function saveDocumentToLocal(cat_ids, cat_urls){
        // Get a reference to the image element
        var storageFiles = ''
        var img_id, storageFilesDate, date, todaysDate, cat_id;
        var obj = [];
    
        storageFiles = JSON.parse(localStorage.getItem("storageFiles")) || {}
        if (typeof storageFiles === "undefined" || storageFiles == null || jQuery.isEmptyObject(storageFiles)) {
            console.log("Store images in locastorage.....")
            for (var i = 0; i < cat_ids.length; i++){
                img_id = document.getElementById(cat_ids[i]);
                storageFilesDate = storageFiles.date;
                date = new Date();
                todaysDate = (date.getMonth() + 1).toString() + date.getDate().toString();
    
                img_id.addEventListener("load", function(){
                    var imgCanvas = document.createElement("canvas");
                    var imgContext = imgCanvas.getContext("2d"); 
    
                    // Make sure canvas is as big as the picture
                    imgCanvas.width = img_id.width;
                    imgCanvas.height = img_id.height;
    
                     console.log("/////" + imgCanvas)
                    // Draw image into canvas element
                    imgContext.drawImage(img_id, 0, 0, img_id.width, img_id.height);
                    
                    // Get canvas contents as a data URL
                    var imgAsDataURL = imgCanvas.toDataURL("assets/img/png");
                    storageFiles.img_id = imgAsDataURL;
    
                    // Set date for localStorage
                    storageFiles.date = todaysDate;
    
                    // Set category_id for localStorage
                    storageFiles.cat_id = this.id;
    
                    try {
                        var test = $.parseJSON(localStorage.getItem("storageFiles"));
                        if(typeof test !== 'undefined' && test !== null){
                            obj = test;       
                        }
                        console.log(storageFiles.img_id)                    
                        obj.push(storageFiles);
                    }
                    catch (e) {
                        console.log("Storage failed: " + e);
                    }            
    
                }, false);
                img_id.setAttribute("src", cat_urls[i]);
            } //For Loop end
        }else{            
            $.each(storageFiles, function(index, category){
                console.log(category);
                img_id = document.getElementById(category.cat_id);
                img_id.setAttribute("src", category.img_id);
            });
    
        }    
       
    }
    
  22. Eric

    Amazing!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Get Node.js Command Line Arguments with yargs

    Using command line arguments within Node.js apps is par for the course, especially when you're like me and you use JavaScript to code tasks (instead of bash scripts).  Node.js provides process.argv but that doesn't provide a key: value object like you'd expect: Bleh.  If you want to work with a...

  • OâReilly Velocity Conference â New York

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • Free Download: Font Bundle Featuring 17 Incredible Typefaces

    The only thing we love more than a good font, is a good free font. So we’ve combed the Web for some of our favorite free fonts, and gathered them here in a single download. You’ll find a variety of useful typefaces, from highly geometric designs...

  • OâReilly Velocity Conference â Amsterdam

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • CanIUse Command Line

    Every front-end developer should be well acquainted with CanIUse, the website that lets you view browser support for browser features.  When people criticize my blog posts for not detailing browser support for features within the post, I tell them to check CanIUse:  always up to date, unlike...