7

I searched a lot but didnt find getting base64 encoded data from clipboard. I can catch paste event and then assign event to variable with this

clipBoard = e.clipboardData ? e.clipboardData : window.clipboardData;

in chrome; i can get print screen which has been paste, like this

if (clipBoard.types[0] == "Files") {
    var blob = clipBoard.items[0].getAsFile();

    var reader = new FileReader();
    reader.onload = function(event){
    console.log(event.target.result);
    }; // data url!
    reader.readAsDataURL(blob);
}

but in ie 11 clipBoard variable has no "items" or "types". i will upload that image server but i didnt get base64 encoded data.

MC_delta_T
  • 616
  • 1
  • 9
  • 22
  • 2
    btw, you should really prefer URL.createObject() over FileReader() if you need a url end-result; it's MUCH faster, a lot simpler (no callbacks), and handles larger files than FileReader(). – dandavis Feb 26 '15 at 19:12
  • i dont know js very well. could you provide some sample code. – MC_delta_T Feb 28 '15 at 07:42

2 Answers2

12

It's possible... on any site :) However, there is no cross-browser method.

In Chrome and Opera (and most probably Safari, but I cannot test it now) you can access the clipboard as you wrote in your question. In fact, this method is just workaround for the Chromium bag Issue 31426.

The following code implements this functionality. Press Alt-PrtScr, click in the editor field and paste. I simply print the image data; in the real program I could send it to my server for the further processing, for example.

$(document).ready(function() {
  $('#editor').on('paste', function(e) {
    var orgEvent = e.originalEvent;
    for (var i = 0; i < orgEvent.clipboardData.items.length; i++) {
      if (orgEvent.clipboardData.items[i].kind == "file" && orgEvent.clipboardData.items[i].type == "image/png") {
        var imageFile = orgEvent.clipboardData.items[i].getAsFile();
        var fileReader = new FileReader();
        fileReader.onloadend = function() {
          $('#result').html(fileReader.result);
        }
        fileReader.readAsDataURL(imageFile);
        break;
      }
    }
  });
});
#editor {
  width: 500px;
  min-height: 40px;
  border: solid 1px gray;
  padding: 4px;
}

#resultcnt {
  width: 100%;
  margin-top: 16px;
}

#result {
  display: block;
  max-width: 90%;
  margin: 16px 0 32px 0;
  font-size: 12px;
  color: blue;
  overflow: visible;
  word-break: break-all;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='editor' contenteditable=true></div>
<div id='resultcnt'>Copyed image src:<br />
  <div id='result'></div>
</div>

In IE and Firefox you can achieve the same result using a different approach. Lucky, these browsers have no problem to paste print screen into editor, so you don't need to access clipboard at all. You just listen to the paste event and using the interval catch the point of time when the image is already created but still not rendered. Then you simply get the image source and empty the editor.

The following code implements this algorithm. When you run it in IE or Firefox the result will be the same as the previous sample's results in Chrome and Opera:

<script type="text/javascript">
$(document).ready(function() {
  
  $('#editor').on('paste', function (e) {
    $('#editor').empty();
  var waitToPastInterval = setInterval(function () {
   if ($('#editor').children().length > 0) {
    clearInterval(waitToPastInterval);
        $('#result').html($('#editor').find('img')[0].src);
        $('#editor').empty();
   }
  }, 1);  
  });
    
});
</script>
<style  type="text/css">
#editor{
  width: 500px;
  min-height: 40px;
  border: solid 1px gray;
  padding: 4px;
}
#resultcnt{
  width: 100%;
  margin-top: 16px;
}
#result{
  display: block;
  max-width: 90%;
  margin: 16px 0 32px 0;
  font-size: 12px;
  color: blue;
  overflow: visible;
  word-break: break-all;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='editor' contenteditable=true></div>
<div id='resultcnt'>Copyed image src:<br />
  <div id='result'></div>
</div>
Praveen Kumar Purushothaman
  • 154,660
  • 22
  • 177
  • 226
Alexander Dayan
  • 2,562
  • 1
  • 13
  • 25
  • yes, i already solve the problem very similar way. in chrome getting image is not problem. but in ie i did some tricks. first defined css rule to hide images in contenteditable div. then find image with jquery and get src parameters value and then send server. – MC_delta_T Mar 02 '15 at 08:35
  • I use this interactive example from time to time to get base64 encoded files if I need them quickly. – luckydonald May 27 '20 at 09:30
2

It is possible... on trusted sites.

You see, IE's clipboardData is pretty well defined. It supports only text or url. Neither WScript nor ActiveXObject provide better clipboard access.

But you can use PowerShell to access .Net, including the Clipboard, which has a nice little method GetImage(). Calling PowerShell is simple through WSH, as is Base64 encoding.

Which leaves only the problem of how to retrieve the extracted data.

Normally you should use a file, since we are already using ActiveX. But for purpose of demonstration, here I will use registry. This saves us the trouble of creating FileSystemObject and detecting temp folder.

The html below will grab whatever image is on the clipboard, in base64, and put it into an <img>.

<!DOCTYPE html><meta charset="utf-8"><img width=500 /><script>
try {
   var doc = document, body = doc.body, shell = new ActiveXObject('WScript.shell');
   var key = 'HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer';
   var cmd = "function Get-ClipImg {Add-Type -AssemblyName 'System.Windows.Forms';"+
      "$s=New-Object System.IO.MemoryStream;"+
      "[System.Windows.Forms.Clipboard]::GetImage().Save($s,[System.Drawing.Imaging.ImageFormat]::Png);"+
      "[Microsoft.Win32.Registry]::SetValue('"+key+"','tmp_clipboard',[System.Convert]::ToBase64String($s.ToArray()))"+
   "} Get-ClipImg";
   shell.run( 'powershell -Command "'+cmd+'"', 0, true );
   var data = shell.RegRead( key + '\\tmp_clipboard' );
   shell.RegDelete( key + '\\tmp_clipboard' );
   if ( ! data.trim() ) body.textContent = 'Clipboard has no image';
   else doc.querySelector('img').src = 'data:image/png;base64,' + data;
} catch ( err ) { body.textContent = err; }
</script>

So, here you are, a way to take clipboard image in IE, without using Flash or Java. As long as the site is trusted. (Local file included)

Or you can use Flash or Java.

Community
  • 1
  • 1
Sheepy
  • 15,393
  • 3
  • 41
  • 67
  • thx for reply but i cant force users to add my site to their trusted site list. – MC_delta_T Feb 28 '15 at 07:43
  • @MC_delta_T Then the only option is to use flash, java, or other plugins. Since IE 11 is likely to be the last IE, it is safe to say that IE will never natively support the options you want. – Sheepy Feb 28 '15 at 17:22