0

I am trying to use Google HTMLService to process a form from the client side. The tricky part is that I want to capture a pasted image (from clip-board) in the form, send it to the server side and save it in the DriveApp.

On the client side, I think I was able to capture the pasted image based on this page: http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/

And my client side code looks like this:

function pasteHandler(e) {
   // We need to check if event.clipboardData is supported (Chrome)
   if (e.clipboardData) {
      // Get the items from the clipboard
      var items = e.clipboardData.items;
      if (items) {
         // Loop through all items, looking for any kind of image
         for (var i = 0; i < items.length; i++) {
            if (items[i].type.indexOf("image") !== -1) {
               // We need to represent the image as a file,
               var blob = items[i].getAsFile();
               // and use a URL or webkitURL (whichever is available to the browser)
               // to create a temporary URL to the object
               var URLObj = window.URL || window.webkitURL;
               var source = URLObj.createObjectURL(blob);
               var reader = new FileReader();
               reader.onload = function(e) {
                 document.getElementById("summaryImage").value= reader.result;
               }
               reader.readAsBinaryString(blob);

               // The URL can then be used as the source of an image
               createImage(source);
            }
         }
      }
   // If we can't handle clipboard data directly (Firefox), 
   // we need to read what was pasted from the contenteditable element
   } 
}

So the change is only that I used a FileReader to read the blob and save it into a hidden field in the form.

<input type="hidden" name="summaryImage" id='summaryImage' value=''>

I think this part is working fine, as I could display the image in the client side and the hidden field is also populated with a byte stream.

What I am unsure about is how to pick up the value of the hidden field, now being a "Binary String" and save it as a proper PNG file in Google Drive and / or view it.

On the server side, I was able to save any uploaded files (using input file form element), but note the binary string passed by the hidden field.

I have tried things like below:

blob = form.summaryImage;
DriveApp.createFile('TRIFILE2.png', blob, 'image/png');

This does create a file, but cannot be viewed as png. If I open it in Google Drive, it shows as below. I suppose it knows this is a PNG file, but what's the correct way to convert it?

‰PNG


IHDR   y   2     Þ  R    IDATx í]mLTYš~Øl€I ÃF  ´šX ‰|Dc H(œ    TÿàcÒÅPkuÂGÿ°è B'*ì: èHÖ    =ÂàØà¸É”ýc¨ùa &–M75i„ ]0ÓR&’¢W£`RZ› ÅA·
LÒ`²¹›s?ªî­ïÂ[x©{ªÛÔ­óñž÷}žûž{îåT=i×JJ ÐWJ# Æ\ %9¥) þ!Åã£á ’¬Š“€f²
h¦$S’U€€
B¤™LIV  * ‘f2%Y  ¨ DšÉ”d   ‚ i&S’U€€
B¤™LIV  * ‘f2%Y  ¨ DšÉ”d   ‚ i&S’U€€
B¤™LIV  * ‘f2%Y  ¨ DšÉ”d   ‚ i&S’U€€
B¤™LIV  * ‘f2%Y  ¨ DšÉ”d   ‚ i&S’U€€
B¤™LIV  * 1 a ú;^)N4 ®Sœ`  %™’¬  T "ÍdJ²
 PAˆ4“)É*@@ !ÒL¦$«   „H3™’¬  T "ÍdJ²
 PAˆ4“)É*@@ !ÒL¦$«   „H3™’¬  T "ÍdJ²
 PAˆ4“)É*@@ !ÒL¦$‹ pc -

I also tried Utilities.newBlob() function, but cannot figure out how to make a correct Blob from the binary string.

Pan Yan
  • 1,622
  • 1
  • 18
  • 21
  • Using the server side logger, I can confirm that form.summaryImage (which is the hidden field passed from the form) contains a byte stream of 89 50 4E 47 0D 0A 1A 0D 0A 00 .... This is very close to the PNG file signature, which should have been 89 50 4e 47 0d 0a 1a 0a. Not sure why?! – Pan Yan Sep 22 '15 at 03:29

1 Answers1

1

Don't use readAsBinaryString, instead use readAsDataURL, which gets a base64, and you won't have that mess of chars.

If you need the server side code you can follow my code and Sandy Good tutorial here:

Uploading Multiple Files to Google Drive with Google App Script

Community
  • 1
  • 1
Kriggs
  • 3,731
  • 1
  • 15
  • 23