📜 ⬆️ ⬇️

HTML5 No Screenshots

I use Gmail almost every day, but I recently noticed that if you take a screenshot of the screen ( www.take-a-screenshot.org ), you can simply copy this screenshot directly into the text of a Gmail letter by pressing Ctrl + V. It works everywhere, but of course except IE. Interested in asking how this happens google the next post on Stackoverflow . Under the strong impression of the HTML5 capabilities, clipboardData decided to make a simple portal, where without any Desktop applications any user can upload a screenshot by simply copying it.


Browser Support


Firstly, it should be noted that in order to copy something from the buffer (for example, a screenshot), the browser must have support for the Clipboard API . As can be seen on caniuse, only the most recent browsers work with this API. IE, unfortunately, smokes on the sidelines despite partial support.

Uploading javascript screenshots


To load an image from the buffer (screenshot), you first need to define a paste event handler:
document.body.addEventListener("paste", function(e) { ... }); 

')
The handler will always be called when an “Insert” event occurs in the working area of ​​the browser window, for example, by pressing Ctrl + V. Next, you need to determine the code that actually receives the image file from the buffer. This code is identical for Chrome and Opera browsers, but different for FireFox, since the latter, for some security reasons, has methods that are not available for the clipboardData object.

Chrome, Opera

 // e.clipboardData.items -         for (var i = 0; i < e.clipboardData.items.length; i++) { //    if (e.clipboardData.items[i].kind == "file" && e.clipboardData.items[i].type == "image/png") { //    Blob ( ) var imageFile = e.clipboardData.items[i].getAsFile(); var fileReader = new FileReader(); fileReader.onloadend = function(e) { //    this.result  Base64  loadImg(this.result); }; //  Blob  DataURL (Base64   ) fileReader.readAsDataURL(imageFile); e.preventDefault(); break; } } 


Firefox

In FireFox, we are unable to read the file via clipboardData. When pasting, the browser itself creates an <img> tag with src as a DataURL. Therefore it is necessary to make a “crutch”:
 //   js,   Mozilla,   ,  (contenteditable) div  //    . if ($.browser.mozilla) { $(document.body).prepend('<div id="temp" contenteditable="true" style="height:1px;width:1px;color:#FFFFFF;"></div>'); $('#temp').focus(); } //   "" document.body.addEventListener("paste", function(e) { if ($.browser.mozilla) { //  Mozilla,      div // (   ,  FireFox  img   ) $('#temp').focus(); //   img (   2, 3, ..., N ) $('#temp img').remove(); //  FireFox   img  callback-     img -    setTimeout(function() { //   FireFox   img  temp div,     DataURL    loadImg($('#temp img').attr('src')); }, 1); return true; } }); 


Where to upload a picture?


You can upload a picture directly to the server, transferring it via POST DataURL or, for example, on canvas as done on Your screen :
 var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ... function loadImg(dataURL) { var imageObj = new Image(); imageObj.onload = function() { var width = this.width, height = this.height; canvas.width = width; canvas.height = height; ctx.drawImage(this, 0, 0, width, height); }; imageObj.src = dataURL; } 


Canvas is convenient because before uploading a screenshot to the server you can edit it: underline, draw, circle, cut, etc.

What happens on the server?


The server must have a POST controller, which would accept the body in Base64 (DataURL) format and decode it into a binary image file, for example png. The controller can be written in any language, for example Java using SpringMVC:
 @RequestMapping(value = "/upload", method = RequestMethod.POST) public @ResponseBody String save(@RequestBody String b64) { File file = null; FileOutputStream out = null; try { //  Output  out = new FileOutputStream("/opt/files/somename.png"); //  Base64       out.write(Base64.decodeBase64(StringUtils.replace(b64, "data:image/png;base64,", ""))); //   IOUtils.closeQuietly(out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return file.getName(); } 


For attention, I note that this StringUtils.replace (b64, "data: image / png; base64,", "") construct is needed to normalize the DataURL transmitted from Javascript. The fact is that when you create a DataURL, you first put its type and format and then comes Base64 view, for example data: image / png; base64, iVBORw0KGgoAAAANSUhEUgAABVYAAAMAC ...

Additionally, you can still check the file size, and if it exceeds a certain maximum, compress in jpg.

Use cases


Your screen service we at Cackle use every day as a quick and easy way to capture the screens of our clients. Unfortunately, there are very few such solutions on the network and those that are inconvenient or work only through Desktop:


Soon we plan to transfer all this functionality to our Online consultant Cackle . Thus, customers will have the opportunity to take a screenshot and transfer the image directly through a consultant to the operator. This is in some sense the best replacement for Co-Browser, as it allows you to show the entire screen (and not just the browser), reduce development costs and minimize errors.

In conclusion, I will say that the project Your screen is completely new and will develop further, therefore I am waiting for your criticism and suggestions on the functionality.

Source: https://habr.com/ru/post/201190/


All Articles