html2canvas not adding dynamically added images - html2canvas

Here is the code snippet:
The PDF generated by this snippet contains, google maps, visual data from anychart.js, and other content. Everything is working fine but there are a few images that are also added dynamically to the HTML page like other things, are not passing to the PDF.
html2canvas($("#content")[0], {allowTaint: false,useCORS: true})
.then(function (canvas) {
var imgData = canvas.toDataURL("image/jpeg", 1.0);
var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height*0.68]);
pdf.addImage(imgData, 'JPG');
pdf.save(`${officerName}_shiftReport(${reportID}).pdf`);
});

Related

Export PNG with cytoscape function cy.png does not include popper.js labels

I have tried to export the PNG related to the graph provided as sample for the integration of popper.js with cytoscape.js, but the exported png does not include the popper content when exported.
The reference sample is: https://cytoscape.org/cytoscape.js-popper/
The refence code to export the PNG is the following one:
var text = window.cy.png({'output': 'blob'});
var name = "test.png";
var type = "image/png";
var a = document.getElementById("downloadpng");
var file = new Blob([text], { type: type });
a.href = URL.createObjectURL(file);
a.download = name;
a.click();
This is the resulting image when exporting cy.png() included a popper.js content
I would say this is the expected behavior: image export in Cytoscape.js takes the Cytoscape.js canvas and exports it as image. The popper.js labels are not in the canvas - they are separate div objects in the DOM. Hence they are not included in the exported image.

save google gauge chart as a png

I am using google charts and have a page of mixed charts, some pie, a column chart and a gauge chart
The page has an option to generate a pdf, so I am converting the charts to PNG to use in the pdf..
all the charts are generated in the same manner, using a div to display the google chart and a hidden div to store the png image
var chart = new google.visualization.Gauge(document.getElementById('gauge'));
var hidden = new google.visualization.Gauge(document.getElementById('gauge_hidden'));
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function () {
gauge_hidden.innerHTML = '<img src="' + chart.getImageURI() + '">';
});
chart.draw(data, options);
this code works fin on he pie and column charts, but on the gauge chart I am seeing
chart.getImageURI is not a function
any ideas how I can get the png?
CHeers
I was facing this same issue, but after some reading i've come to this solution:
I'm using jQuery to make this a little easier.
First, use XMLSerializer to convert the SVG chart to a string and then use btoa to convert that to base64.
You can use this string this way:
var s = new XMLSerializer().serializeToString($(chart_div).find('svg')[0]);
var base64String = "data:image/svg+xml;base64," + window.btoa(s);
In my case i needed to draw the gauge chart to a PDF and DOMPDF doesn't support this format, so if you need a "data:image/png;base64," string, you can continue with this solution.
You need to set the "svg+xml;base64" as src of a new Image and then draw that image to a Canvas. After that you can use toDataURL method from canvas to get the content as base64 png.
var s = new XMLSerializer().serializeToString($(chart_div).find('svg')[0]);
var image = new Image();
image.width = 640;
image.height = 480;
image.src = 'data:image/svg+xml;base64,' + window.btoa(s);
var myCanvas = document.createElement('canvas');
myCanvas.width = 640;
myCanvas.height = 480;
var myCanvasContext = myCanvas.getContext('2d');
myCanvasContext.drawImage(image,0,0);
// get google chart gague to base64, yey!
var base64String = myCanvas.toDataURL();
Thanks to the author of this answer and this post

saving data from html canvas to mongodb collection

A Meteor client code displays a canvas for user signature and option to save it to the user collection to be fetched later for inserting into future html report pages which will also need to be signed.
What is the general outline to achieve this and how to do it?
//client
let imgData = ctx.getImageData(0, 0, width, height);
Meteor.call('saveImageToUser', imgData);
//server
Meteor.methods({
'saveImageToUser': (img) => {
Meteor.users.update(userId, {
signature: img
})
}
});
I've done the same thing in one of my web apps.
My html:
<canvas id="simple_sketch" width="400" height="400"></canvas>
My client js :
var canvas = $(#simple_sketch")[0].toDataURL();
Meteor.call('saveImageToUser', canvas);
My method (remember due to meteor's user object you must save it in the profile object of the user.
'saveImageToUser' : img => {
Meteor.users.update(userId, {
'profile.signature' : img
})
}

Image uploaded from Mobile phone to Angular is sideways or upside down

I am able to upload images from my desktop to an Angular based Web Application overlayed on SharePoint without issue, but if I upload from a Mobile phone, such as an iPhone, using the take "Take Photo or Video" or "Photo Library" function, it causes the image to be sideways when taken in portrait or upside down when taken in landscape. Here is my current upload function. Any clues/have others had the same issues uploading to Mobile Web Applications from iPhones/Mobile Phones to a SharePoint library?
Here is my upload function:
// Upload of images
$scope.upload = function () {
//console.log($scope.files);
if (document.getElementById("file").files.length === 0) {
alert('No file was selected');
return;
}
var parts = document.getElementById("file").value.split("\\");
var uploadedfilename = parts[parts.length - 1];
var basefilename = uploadedfilename.split(".")[0];
var fileextension = uploadedfilename.split(".")[1];
var currentdate = new Date();
var formatteddate = $filter('date')(new Date(currentdate), 'MMddyy-hmmssa');
var filename = basefilename + formatteddate + '.' + fileextension;
var file = document.getElementById("file").files[0];
uploadFileSync("/sites/asite", "Images", filename, file);
}
//Upload file synchronously
function uploadFileSync(spWebUrl, library, filename, file)
{
console.log(filename);
var reader = new FileReader();
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
var buffer = evt.target.result;
var completeUrl = spWebUrl
+ "/_api/web/lists/getByTitle('"+ library +"')"
+ "/RootFolder/Files/add(url='"+ filename +"',overwrite='true')?"
+ "#TargetLibrary='"+library+"'&#TargetFileName='"+ filename +"'";
$.ajax({
url: completeUrl,
type: "POST",
data: buffer,
async: false,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-length": buffer.byteLength
},
complete: function (data) {
console.log(data);
},
error: function (err) {
alert('failed');
}
});
}
};
reader.readAsArrayBuffer(file);
}
The output of these is just pushed into an array for use in an Angular UI Carousel:
// Control of Image Carousel
$scope.myInterval = 0;
// Population of carousel
$scope.slides = [];
appImages.query({
$select: 'FileLeafRef,ID,Created,Title,UniqueId',
$filter: 'ReportId eq ' + $routeParams.Id + ' and DisplayinReport eq 1',
}, function (getimageinfo) {
// Data is within an object of "value"
var image = getimageinfo.value;
// Iterate over item and get ID
angular.forEach(image, function (imagevalue, imagekey) {
$scope.slides.push({
image: '/sites/asite/Images/' + imagevalue.FileLeafRef,
});
});
});
The image carousel is on page as follows:
<div style="height: 305px; width: 300px">
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;height:300px">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
IMPORTANT: The images are sideways and upside down upon upload to the SharePoint library, so irrespective of outputting them, they seem to be misoriented when they hit the destination library I am using as a source to display on page.
How do I upload the images so SharePoint respects the EXIF data/orientation?
It may be related to EXIF. See JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images
If you want a better answer, we will need the code which show the image, and the code server side.
UPDATE : I'm not an expert at all on SharePoint, but you can found a lot about it in the SharePoint Stack Exchange. For example, https://sharepoint.stackexchange.com/questions/131552/sharepoint-rotating-pictures-in-library, should do the trick.
To sum up a little : in your case, their could be a lot of cases to study. So, I recommended you auto-correct the exif, and then permit to your user to correct it if the auto-correct was wrong. Their is a lot of tools to do that. If you want to do it server-side, look at the link above, and if you want to do it on the client side, you could use JS-Load-Image for example.

jScrollPane contentPane not reinitialising when img src changes

My objective is to load dynamically various landscape panoramic images into the jScrollPane container and reinitialise so that the scrollbar would be re-calculated based on the current img dimensions.
My problem is that although I'm injecting the img src and then calling the api.reinitialise() method, it's not updating. Therefore the img loads, but the scrolling pane is still the same width.
I'm assume it has something to do with jScrollPane not being able to retrieve the new img dimensions in time to reinitialise with the right width.
HTML
<div class="px-content">
<img src="" />
</div>
JS
var scrollPane = $('.px-content').jScrollPane({hideFocus: true, showArrows: true, autoReinitialise: true});
var api = scrollPane.data('jsp');
var loadImage = function(id){
var image, $paneContent, $img;
imageSource= this.get(id); // returns an image URL
$paneContent = this.jspAPI.getContentPane();
$img = $paneContent.find('img').attr('src', imageSource);
api.reinitialise();
}
loadImage(0); // loads correctly
loadImage(1); // loads img correctly, but pane doesn't refresh to new width
Any ideas? Happy to try anything.
Seb.