Convert html to canvas and download as zip file - javascript

I am trying to download different sections of a page as jpeg. There are two ways I'm going about it; One is to include a download button in every section and when it is clicked, the section is downloaded as jpeg; The other is to include a button atop the page and when it is clicked, all the sections are downloaded.
The download section by section code works well but the issue arises when I try to do the download all option, It downloads files of type file instead of jpeg pictures.
When I logged the url I'm supposed to download from, I find out that it is empty but it isn't inside the html2canvas function.
I am using html2canvas to convert html to canvas and JSZip to zip it.
function urlToPromise(url) {
return new Promise(function(resolve, reject) {
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
reject(err);
} else {
resolve(data);
console.log(data);
}
});
});
}
function getScreen(){
var caption = $('#caption-input').val();
var allSections = $("#content").children().unbind();
var allSectionsArray = $.makeArray(allSections);
console.log(allSectionsArray);
var zip = new JSZip(); //Instantiate zip file
var url = "";
for(var i = 0; i < allSectionsArray.length; i++){
console.log("Currently at " + allSectionsArray[i].id);
var queryId = allSectionsArray[i].id.toString();
html2canvas(document.querySelector("#"+queryId)).then(function(canvas) {
$("#blank").attr('href',canvas.toDataURL('image/jpeg', 1.0));
$("#blank").attr('download',caption + ".jpeg");
//$("#blank")[0].click();
url = $("#blank").attr('href');
console.log(url);
});
console.log(url);
var filename = "image " + (i+1);
zip.file(filename, urlToPromise(url),{binary:true}); //Create new zip file with filename and content
console.log('file ' + (i+1) + ' generated');
console.log(filename+ "\n" + url);
}
//Generate zip file
generateZipFile(zip);
}
function generateZipFile(zip){
zip.generateAsync({type:"blob"})
.then(function callback(blob) {
saveAs(blob, "example.zip");
console.log("zip generated");
});
}

Related

In Cordova Android, jsPDF addImage from Canvas Signature is not writing correctly when write to PDF file

This is DataURL from SignaturePad
var imageURI = signaturePad.toDataURL();
This is for Writing to PDF using jsPDF
var pdf = new jsPDF('p','pt','a4');
var d = new Date().toISOString().slice(0, 19).replace(/-/g, "");
var filename = 'sign_' + d + '.pdf';
pdf.text(20, 20, 'YES, Inside of Cordova!');
pdf.addImage(imageURI, 'PNG', 20, 50);
pdf.save(filename);
var pdfOutput = pdf.output();
This is for saving in Android
window.resolveLocalFileSystemURL(cordova.file.externalCacheDirectory, function(dir) {
console.log("Access to the directory granted succesfully");
dir.getFile('sign.pdf', {create:true}, function(file) {
console.log("File created succesfully.");
file.createWriter(function(fileWriter) {
console.log("Writing content to file");
fileWriter.write(pdfOutput);
}, function(){
alert('Unable to save file in path '+ cordova.file.externalCacheDirectory);
}
);
});
});
But the Signature is not correctly write in Pdf.
when I draw in Signature
when I draw in Signature
but the Pdf in show
but the Pdf in show

Read pdf file with HTML5 File API

I want to make a form with React and upload pdf files. I've to implement until here but now my app needs to read data from pdf without saving in backend database etc. The whole functionality works as pre-checker.
Any suggestion?
You can use PDF.js to read the content of PDF file using javascript/jQuery. Here is my working example.
$("#file").on("change", function(evt){
var file = evt.target.files[0];
//Read the file using file reader
var fileReader = new FileReader();
fileReader.onload = function () {
//Turn array buffer into typed array
var typedarray = new Uint8Array(this.result);
//calling function to read from pdf file
getText(typedarray).then(function (text) {
/*Selected pdf file content is in the variable text. */
$("#content").html(text);
}, function (reason) //Execute only when there is some error while reading pdf file
{
alert('Seems this file is broken, please upload another file');
console.error(reason);
});
//getText() function definition. This is the pdf reader function.
function getText(typedarray) {
//PDFJS should be able to read this typedarray content
var pdf = PDFJS.getDocument(typedarray);
return pdf.then(function (pdf) {
// get all pages text
var maxPages = pdf.pdfInfo.numPages;
var countPromises = [];
// collecting all page promises
for (var j = 1; j <= maxPages; j++) {
var page = pdf.getPage(j);
var txt = "";
countPromises.push(page.then(function (page) {
// add page promise
var textContent = page.getTextContent();
return textContent.then(function (text) {
// return content promise
return text.items.map(function (s) {
return s.str;
}).join(''); // value page text
});
}));
}
// Wait for all pages and join text
return Promise.all(countPromises).then(function (texts) {
return texts.join('');
});
});
}
};
//Read the file as ArrayBuffer
fileReader.readAsArrayBuffer(file);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.87/pdf.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<input type="file" id="file" name="file" accept="application/pdf">
<br>
<p id="content"></p>
</body>

Unable to download dynamic image in ionic

hey i am creating a app in which dynamic images should be download from the net but some cant able to download kindly check the code below and give some suggestion to download and also tell how to pass dynamic image link in social share plugin in ngcordova .
$
scope.downloadImage = function() {
$http.get('http://sabkideal.com/phpapi_/cashback.php').success(function(response) {
$scope.data = response;
for (var i=0 ;i <response.length; i++)
{
var url = response[i].image;
var deal = response[i].id;
//url showing the same url every time i click and not jumping to next statement when click on send image download .
console.log(deal);
console.log(url);
var filename = url.split("/").pop ;
console.log(filename);
var targetPath = encodeURI(cordova.file.dataDirectory + fileName);
console.log(targetPath);
var options = {};
var trustHosts = true;
}
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(
function(result) {
alert('Download success');
refreshMedia.refresh(targetPath);
},
function(err) {
alert('Error: ' + JSON.stringify(err));
},
function(progress) {
// progressing download...
})
});
}

Is there a way not to let a blob (createObjectURL) show the image which is a GIF file but has a .jpeg extension?

Using blueimp, I'm making a file upload module and I will show an image thumbnail before people upload the image.
My code contains the following:
$('.fileupload').fileupload({
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(jpe?g|png)$/i,
maxNumberOfFiles: 1,
maxFileSize: 3000000,//3MB
loadImageMaxFileSize: 3000000,//3MB
}).on('fileuploadsubmit', function (e, data) {
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('.files');
$.each(data.files, function (index, file) {
// ファイル情報を表示する
var node = $('<p/>')
.append($('<span/>').text(file.name));
// プレビューを表示する
if (!index) {
node.append('<br>');
if((/\.(jpe?g|png)$/i).test(data.files[0].name))
{
node.append('<img class= "uploaded-image" src="'
+ URL.createObjectURL(data.files[0]) + '"/><br>');
}
node.append(uploadButton.clone(true).data(data))
.append(cancelButton);
}
node.appendTo(data.context);
});
}) // .on(... code following
It works well, but if people change a GIF file extension to ".jpeg" and upload it, the blob will also work well to show the GIF and, I think it's not safe. Is there a way not let blob to show the thumbnail In this case?
When submit the file, I'm checking the file in the server side if the file is really an image file (although it has a valid extension).
(this link helped me)
The code below worked well:
if (!index) {
node.append('<br>');
if((/\.(jpe?g|png)$/i).test(data.files[0].name))
{
if (window.FileReader && window.Blob)
{
var blob = data.files[0]; // See step 1 above
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for(var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
if((header == "89504e47") || (header.substr(0,6) == "ffd8ff"))
{
$("button.upload").before('<img class= "uploaded-image" src="' + URL.createObjectURL(data.files[0]) + '"/><br>');
$(".file_upload").attr("style", "height: 600px; overflow-y: auto");
}
else
{
$("button.upload").prop('disabled', true);
var error = $('<span class="text-danger"/>').text(msg[4]);
$('.files').append('<br>').append(error);
}
};
fileReader.readAsArrayBuffer(blob);
}
}
node.append(uploadButton.clone(true).data(data))
.append(cancelButton);
}

Image upload to server in node.js without using express

Below is my server code where I try to get the file that was uploaded. However, fs.writeFiledoesn't work, so I'm assuming that I'm doing something wrong.
server.on('request', function(request, response){
....
if((pathArray[1] == "photos") && (pathArray[2] = "new")){
var imagesPath = './images';
uploadPhoto(response, imagesPath);
}
else if(path == '/document/save'){
console.log("path: " + path);
var body = '';
request.on('data', function(data){
body += data;
});
request.on('end', function() {
var note = querystring.parse(body);
console.log("Body data: " + note);
var newPath = "./images/myimage.jpg";
fs.writeFile( newPath, body, function (err) {
if (err) throw err;
});
});
}
Here is my HTML for the form, if it helps anyone:
function uploadPhoto(response, imageLoc){
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write('<html><body>');
response.write('<div class="uploadFile">');
response.write('<link rel="stylesheet" type="text/css" href="style.css">');
response.write('<form action =/document/save>');
response.write('<method = "post">');
response.write('<enctype="multipart/form-data">');
response.write('<label for="name">Upload new photo</label>');
response.write('<br></br>');
response.write('<input type="file" name="name">');
response.write('<br></br>');
response.write('<button type="submit">Upload</button>');
response.write('</div>');
response.write('</body></html>');
response.write('</form>');
response.end();
}
After I upload the file, url goes to /document/save/uploadImage.jpg. But when I try to read the content of the image ("body") to save the image into a folder and then display it, seems that the content of the object of the request is empty.
How do I get the content of the image using node.js without express, or any other external libraries than what I have? Is fs.writeFile a good function to use when writing a binary file?
What has to be taken into consideration is the fact that the received data from the upload has this sort of format:
------WebKitFormBoundary9BhXe3lt2UddCDz9
Content-Disposition: form-data; name="document"; filename="globeSS.jpg"
Content-Type: image/jpeg
ÿØÿà JFIF d d ÿì Ducky d ÿá
//[binary binary binary...]
Ï[leñnœ“}ÛOyŠVÑ0êãXÂ}Ö'±”É iÉöÚ$GTQ7äŽø
uÚ_êÍòXgV¿Õ=€q`]a­KRÐÀ
ò<ÿÙ
------WebKitFormBoundary9BhXe3lt2UddCDz9--
To get the binary data only( and thus the file), the programmer has to figure out a way to clip the binary out of that data. In the below code, binary of the picture is all saved in memory, so if the user uploads a particularly large file, the following implementation might fail. It'd be best to try to write down the file in chucks.
request.setEncoding('binary');
//Grabbing all data from the image
var body = ''
var binaryEnd; //gets the string that indicates the location of the end of the binary file
var first = true;
request.on('data', function(data) {
if(first)
binaryEnd = data.toString().substring(0, data.toString().indexOf('\n')-1);
first = false;
body += data
});
//Dealing with the image once we have everything
request.on('end', function() {
var note = querystring.parse(body, '\r\n', ':')
console.log(note)
//making sure than an image was submitted
if (note['Content-Type'].indexOf("image") != -1)
{
//get the filename
var fileInfo = note['Content-Disposition'].split('; ');
for (value in fileInfo){
if (fileInfo[value].indexOf("filename=") != -1){
fileName = fileInfo[value].substring(10, fileInfo[value].length-1);
if (fileName.indexOf('\\') != -1)
fileName = fileName.substring(fileName.lastIndexOf('\\')+1);
console.log("My filename: " + fileName);
}
}
//Get the type of the image (eg. image/gif or image/png)
var entireData = body.toString();
var contentTypeRegex = /Content-Type: image\/.*/;
contentType = note['Content-Type'].substring(1);
//Get the location of the start of the binary file,
//which happens to be where contentType ends
var upperBoundary = entireData.indexOf(contentType) + contentType.length;
var shorterData = entireData.substring(upperBoundary);
//replace trailing and starting spaces
var binaryDataAlmost = shorterData.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
//Cut the extra things at the end of the data (Webkit stuff)
var binaryData = binaryDataAlmost.substring(0, binaryDataAlmost.indexOf(firstLine));
//Write to a file
fs.writeFile('./images/' + fileName , binaryData, 'binary', function(err)
{
//forward to another location after writing data
response.writeHead(302, {
'location':'/index.html'
});
response.end();
});
}
else
respond(404, "Please input an image", response);
});
This should work in all browsers (please note that internet explorer does not limit its data with ------WebkitFormBoundary, but something else (I think only -----, but I forgot.)

Categories