Upload Image by Copy and Paste

HTML5 has a very good file upload API. If your application deals with uploading image files, you can make users life even easier by allowing her to paste image data from the OS clipboard. Here, HTML5 clipboard API will come to the rescue. In this article, we will build a complete implementation.

First, create a basic HTML5 page with a <div> where we will paste data.

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
//Code will go here

</script>
</head>
<body>
<div style="width: 200px; height: 200px; background: grey" id="pasteTarget">
Click and paste here.
</div>
</body>
</html>

Next, within the <script> element, add this function to register the paste event handler.

window.onload = function() {
    document.getElementById("pasteTarget").
        addEventListener("paste", handlePaste);
};

Implement handlePaste() as follows:

function handlePaste(e) {
    for (var i = 0 ; i < e.clipboardData.items.length ; i++) {
        var item = e.clipboardData.items[i];
        console.log("Item type: " + item.type);
        if (item.type.indexOf("image") != -1) {
            uploadFile(item.getAsFile());
        } else {
            console.log("Discarding non-image paste data");
        }
    }
}

The getAsFile() method gives us access to the image data as a HTML5 file object. We can now use XMLHttpRequest Level 2 API to upload the data using Ajax. Implement uploadFile() as follows.

function uploadFile(file) {
    var xhr = new XMLHttpRequest();

    xhr.upload.onprogress = function(e) {
        var percentComplete = (e.loaded / e.total) * 100;
        console.log("Uploaded: " + percentComplete + "%");
    };

    xhr.onload = function() {
        if (xhr.status == 200) {
            alert("Sucess! Upload completed");
        } else {
            alert("Error! Upload failed");
        }
    };

    xhr.onerror = function() {
        alert("Error! Upload failed. Can not connect to server.");
    };

    xhr.open("POST", "FileUploader", true);
    xhr.setRequestHeader("Content-Type", file.type);
    xhr.send(file);
}

That’s it for the client side. Now, you can write a server side handler, for example a Servlet, to receive the pasted image data.

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
    InputStream is = request.getInputStream();

    //Read the file contents from the input stream
    byte buff[] = new byte[256];
    int len;
    System.out.println("Dumping paste data of type: " + request.getContentType());

    while ((len = is.read(buff)) > 0) {
        //Do something with the buffer
    }
}

For a fully working example, grab this GitHub repo.

13 thoughts on “Upload Image by Copy and Paste

  1. Thank you so much for this compact and complete example!

    For a proof of concept, it was very easy to adopt it to Python using Flask on the server side:

    @app.route(‘/FileUploader’, methods=[‘POST’])
    def fileUploader():
    app.logger.info(‘data: %r’ % len(request.data))
    file(‘test.png’, ‘w’).write(request.data)
    return ‘ok’ # to send the status_code 200

  2. Hi, thanks for the great example. Works perfectly in Google Chrome, however, in the Safari, IE and Firefox seems it doesn’t work. Any idea what’s going wrong?

    Bp7

  3. Thank you for the useful documentation. I haven’t been able to use it directly because I’m working with grails / groovy so I had to make a few adaptation, but the code is quite the same.
    I also needed to redirect the written image to an appropriate folder inside the appserver to be backed up. For anyone who had the same issue here is the grails controller action implementation, as you can see the arrays has been changed to groovy lists and the save path has been changed to application location :

    def pasteDocument() {
    //render (“image reçue”);

    String mimeType = request.getContentType();
    String extension = null;
    def supportedFormatTable = [
    [“image/png”, “png”],
    [“image/jpeg”, “jpg”],
    [“image/gif”, “gif”]
    ];

    //logger.info(“Paste data of type: ” + request.getContentType());

    for (int i = 0; i 0) {
    os.write(buff, 0, len);
    }
    os.close();

    //Show the file name in browser
    //PrintWriter out = response.getWriter();

    //render(“Save request with params” + params);
    render(“Saved image to: ” + saveTo.getAbsolutePath());
    }

    • Hi, I don’t know how to work with PHP to read data from a request body stream. But this should be a fairly common task and well documented somewhere.

  4. Pingback: My Site ~

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.