Paste the Image from System in Html page using javascript

后端 未结 2 415
余生分开走
余生分开走 2021-01-31 03:51

Hi i am creating an web chat application in that i want user can copy paste the image from desktop or can paste directly the screen shot but i am unable to achieve it. I used fo

相关标签:
2条回答
  • 2021-01-31 04:03

    Demo

    Works on latest chrome/firefox. Chrome implementation is simple. Firefox has restrictions that user must give command to do paste like keyboard event and editable input must be focused, so we do tricks here - on ctrl down we focusthat input field, on release unfocus.

    HTML:

    <canvas style="border:1px solid grey;" id="my_canvas" width="300" height="300"></canvas>
    

    JS:

    var CLIPBOARD = new CLIPBOARD_CLASS("my_canvas", true);
    
    /**
     * image pasting into canvas
     * 
     * @param string canvas_id canvas id
     * @param boolean autoresize if canvas will be resized
     */
    function CLIPBOARD_CLASS(canvas_id, autoresize) {
        var _self = this;
        var canvas = document.getElementById(canvas_id);
        var ctx = document.getElementById(canvas_id).getContext("2d");
        var ctrl_pressed = false;
        var reading_dom = false;
        var text_top = 15;
        var pasteCatcher;
        var paste_mode;
    
        //handlers
        document.addEventListener('keydown', function (e) {
            _self.on_keyboard_action(e);
        }, false); //firefox fix
        document.addEventListener('keyup', function (e) {
            _self.on_keyboardup_action(e);
        }, false); //firefox fix
        document.addEventListener('paste', function (e) {
            _self.paste_auto(e);
        }, false); //official paste handler
    
        //constructor - prepare
        this.init = function () {
            //if using auto
            if (window.Clipboard)
                return true;
    
            pasteCatcher = document.createElement("div");
            pasteCatcher.setAttribute("id", "paste_ff");
            pasteCatcher.setAttribute("contenteditable", "");
            pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;';
            pasteCatcher.style.marginLeft = "-20px";
            pasteCatcher.style.width = "10px";
            document.body.appendChild(pasteCatcher);
            document.getElementById('paste_ff').addEventListener('DOMSubtreeModified', function () {
                if (paste_mode == 'auto' || ctrl_pressed == false)
                    return true;
                //if paste handle failed - capture pasted object manually
                if (pasteCatcher.children.length == 1) {
                    if (pasteCatcher.firstElementChild.src != undefined) {
                        //image
                        _self.paste_createImage(pasteCatcher.firstElementChild.src);
                    }
                }
                //register cleanup after some time.
                setTimeout(function () {
                    pasteCatcher.innerHTML = '';
                }, 20);
            }, false);
        }();
        //default paste action
        this.paste_auto = function (e) {
            paste_mode = '';
            pasteCatcher.innerHTML = '';
            var plain_text_used = false;
            if (e.clipboardData) {
                var items = e.clipboardData.items;
                if (items) {
                    paste_mode = 'auto';
                    //access data directly
                    for (var i = 0; i < items.length; i++) {
                        if (items[i].type.indexOf("image") !== -1) {
                            //image
                            var blob = items[i].getAsFile();
                            var URLObj = window.URL || window.webkitURL;
                            var source = URLObj.createObjectURL(blob);
                            this.paste_createImage(source);
                        }
                    }
                    e.preventDefault();
                }
                else {
                    //wait for DOMSubtreeModified event
                    //https://bugzilla.mozilla.org/show_bug.cgi?id=891247
                }
            }
        };
        //on keyboard press - 
        this.on_keyboard_action = function (event) {
            k = event.keyCode;
            //ctrl
            if (k == 17 || event.metaKey || event.ctrlKey) {
                if (ctrl_pressed == false)
                    ctrl_pressed = true;
            }
            //c
            if (k == 86) {
                if (document.activeElement != undefined && document.activeElement.type == 'text') {
                    //let user paste into some input
                    return false;
                }
    
                if (ctrl_pressed == true && !window.Clipboard)
                    pasteCatcher.focus();
            }
        };
        //on kaybord release
        this.on_keyboardup_action = function (event) {
            k = event.keyCode;
            //ctrl
            if (k == 17 || event.metaKey || event.ctrlKey || event.key == 'Meta')
                ctrl_pressed = false;
        };
        //draw image
        this.paste_createImage = function (source) {
            var pastedImage = new Image();
            pastedImage.onload = function () {
                if(autoresize == true){
                    //resize canvas
                    canvas.width = pastedImage.width;
                    canvas.height = pastedImage.height;
                }
                else{
                    //clear canvas
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                }
                ctx.drawImage(pastedImage, 0, 0);
            };
            pastedImage.src = source;
        };
    }
    

    Safari doesn't implement DataTransfer.items, so there's no way to extract image data (i.e. a screenshot copied to the clipboard) in Javascript. You can get copied files, but not data.

    [From stakeoverflow post]

    0 讨论(0)
  • 2021-01-31 04:24

    Chrome

    Add your code to he code from codepen and give an id to the div (line 50)

    Include your script as posted above with the divs id

    $("#one").on("paste", function (event) {
    
      var items = (event.clipboardData || event.originalEvent.clipboardData).items;
      console.log(JSON.stringify(items)); // will give you the mime types
      for (index in items) {
        var item = items[index];
        if (item.kind === 'file') {
          var blob = item.getAsFile();
          var reader = new FileReader();
          reader.onload = function (event) {
            console.log(event.target.result)
          }; // data url!
          reader.readAsDataURL(blob);
        }
      }
    
    })
    

    Make a screenshot, select the first div (that one with the id one), hit ctrl+v, the screenshot appears in the div and the imagedata is loged to console.

    Firefox Use the code I prepeared you within this fiddle

    <html>
    <head>
      <meta charset="utf-8">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
      <style>
        #one {
          border: 1px solid black;
          min-height: 100px;
          min-width: 100px;
        }
      </style>
    </head>
    
    <body>
      Copy image from clipboard in Firefox.
      <br /> Select the box below and paste a image from clipboard via ctrl+v
      <br /> Data printed at console
      <br />
      <div id="one" contenteditable="true"></div>
    
      <script>
        $(function () {
          $("#one").bind("input paste", function (ev) {
            window.setTimeout(function (ev) {
              var input = $("#one").children()[0].src;
              var s = input.split(',');
              var mime = s[0];
              var data = s[1];
              console.log(mime);
              console.log(data);
            }, 300);
          });
        });
      </script>
    </body>
    
    </html>
    

    Chrome & Firefox combined

    A combined version, using the code from @pareshm for Chrome and my code for Firefox may be found in this updated fiddle (Tested with clipboard content created via system screendump by ctrl+print and copy image part from gimp)

    0 讨论(0)
提交回复
热议问题