Paste image from clipboard into document

125 views
Skip to first unread message

Matt Parizeau

unread,
Dec 29, 2016, 3:09:38 PM12/29/16
to PDFTron WebViewer
Q:

Is it possible to paste an image from the clipboard into a document in WebViewer?

A:

Yes you can add it as a stamp annotation in the document. In the example code there's also examples of how to constrain the size of the stamp to fit the page and maintain the correct orientation if the document is rotated.

$(document).one('documentLoaded', function() {
  $
('html').on('paste', function(e) {
    getImageFromClipboard
(e.originalEvent.clipboardData, addStamp);
 
});
});

function getImageFromClipboard(clipboardData, callback) {
 
var matchType = /image.*/;
 
var found = false;
 
return Array.prototype.forEach.call(clipboardData.types, function(type, i) {
   
var file, reader;
   
if (found) {
     
return;
   
}
   
if (type.match(matchType) || clipboardData.items[i].type.match(matchType)) {
      file
= clipboardData.items[i].getAsFile();
      reader
= new FileReader();
      reader
.onload = function(evt) {
        callback
(evt.target.result);
     
};
      reader
.readAsDataURL(file);
     
return found = true;
   
}
 
});
}

function getImageSize(imageData, callback) {
 
var image = document.createElement('img');
  image
.onload = function() {
    callback
({
      width
: image.width,
      height
: image.height
   
});
 
};
  image
.src = imageData;
}

function constrainSize(size, pageSize, rotation) {
 
var width = size.width;
 
var height = size.height;
 
if (rotation === 90 || rotation === 270) {
   
var temp = width;
    width
= height;
    height
= temp;
 
}

 
var aspectRatio = width / height;
 
var pageWidth = pageSize.width;
 
var pageHeight = pageSize.height;
  width
= Math.min(width, pageWidth);
  height
= Math.min(height, pageHeight);
 
// if the aspect ratio has changed we need to make sure we maintain it
 
if ((width / height) !== aspectRatio) {
   
if (height * aspectRatio < width) {
     
// the height is constraining the ratio
      width
= height * aspectRatio;
   
} else {
     
// the width is constraining the ratio
      height
= width / aspectRatio;
   
}
 
}

 
return {
    width
: width,
    height
: height
 
};
}

function addStamp(imageData) {
  getImageSize
(imageData, function(size) {
   
var docViewer = readerControl.docViewer;
   
var annotManager = docViewer.getAnnotationManager();
   
var currentPage = docViewer.getCurrentPage();

   
var pageSize = {
      width
: docViewer.getPageWidth(currentPage - 1),
      height
: docViewer.getPageHeight(currentPage - 1)
   
};
   
var rotation = docViewer.getCompleteRotation(currentPage) * 90;

   
var finalSize = constrainSize(size, pageSize, rotation);

   
var stampAnnot = new Annotations.StampAnnotation();
    stampAnnot
.PageNumber = currentPage;
    stampAnnot
.X = 0;
    stampAnnot
.Y = 0;
    stampAnnot
.Width = finalSize.width;
    stampAnnot
.Height = finalSize.height;
    stampAnnot
.Author = annotManager.getCurrentUser();
    stampAnnot
.Rotation = rotation;
    stampAnnot
.ImageData = imageData;
    annotManager
.addAnnotation(stampAnnot);
    annotManager
.drawAnnotations(stampAnnot.PageNumber);
 
});
}

Christian Gruber

unread,
Sep 22, 2017, 1:30:37 PM9/22/17
to PDFTron WebViewer
I have detected following bug regarding this feature.

When I copy an external picture (from explorer), the image is pasted correctly. Now when I add an annotation to the document and copy & paste the annotation, the image from before gets pasted again. 

Is it possible to determine the last copied element? 

Christian Gruber

unread,
Sep 27, 2017, 6:34:46 PM9/27/17
to PDFTron WebViewer
Any idea? 

Matt Parizeau

unread,
Sep 27, 2017, 7:01:25 PM9/27/17
to PDFTron WebViewer
The reason this is happening is because the annotation copy and paste in WebViewer isn't a real OS copy/paste and doesn't go to the real clipboard, it only stays within a WebViewer "clipboard".

Pasting the annotation and pasting the image are triggered from two separate events so you could block one or the other if they're both being triggered. However I'm not sure you would be able to determine which one was the last that had happened. If you copy an image outside of the browser you don't get an event that something was added to the clipboard so you wouldn't be able to know that a copy on the OS clipboard had happened last.

You might be able to do something like the following:
1. On an annotation copy trigger an update of the OS clipboard to put an empty string there. Annotation copying code is in ReaderControl.js, look for am.updateCopiedAnnotations().
2. On an annotation paste check if there is anything on the OS clipboard and only paste if there is an empty string. I'm not sure you'll be able to programmatically check the clipboard from here, you might have to move this code to the html paste event like in this custom code.

If there is a possible solution hopefully this should get you started.

Matt Parizeau
Software Developer
PDFTron Systems Inc.

On Wednesday, September 27, 2017 at 3:34:46 PM UTC-7, Christian Gruber wrote:
Any idea? 
Reply all
Reply to author
Forward
0 new messages