Adding regular png images was no problem with jsPDF, but now i send a generated image from my server and the browser console displays this error when rendering the PDF file:
Incomplete or corrupt PNG file
obviously the image is not incomplete or corrupt because i can see the response from the server and the image is fine.
Also to avoid render the pdf file before the image is ready i make a check to a that holds the image value variable if is undefined/null.
the format of my image is
var image = "data:image/png;base64,iVBORw0KGgoAAAANSUh...etc";
What could be the problem?
Edit: i changed the format of the image to jpg and this error shows
Supplied data is not a JPEG
if i use this library jspdf.plugin.addimage.js the images are rendered correctly but not the png images.
edit: 2 i made a solution modifying the jspdf.plugin.addimage.js file function addImage, i just changed the name of the function and added those generated images to pdf with that function, since the version of jspdf.min.js has the same name for the same function with this way it won't override the function i can use the one that works with normal images and the ones generated by the server.
This type of error occurs because the image has not finished loading when you send to jsPdf, use onLoad event to check the image loaded completely. for Example -
/* where src = full image url
callback = is callback function
outputFormat = image output format */
function toDataUrl(src, callback, outputFormat) {
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
/*image completely converted to base64string */
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
/* call back function */
callback(dataURL);
};
img.src = src;
if (img.complete || img.complete === undefined) {
img.src = appConfig.config.dummyImage;
img.src = src;
}
}
function callbackBase64(base64Img)
{
/*base64Img contains full base64string of image */
console.log(base64Img);
}
call above function and get base64string of image -
toDataUrl('http://example1.com/image1.jpg', callbackBase64(base64Img), "image/png");
Related
I am trying to send an image to a server for my chrome extension. I am using code from a previous discussion --> how to send image to server with http.post in javascript and store base64 in mongodb.
My problem is that the image is never actually uploaded to the page. For instance, I am trying to upload the image to this input on server that is not mine: image upload section. After the code runs the image section is not uploaded with an image, which is ultimate goal of my program.
This is what the terminal looks like after all the console.log()'s run: enter image description here
Does anyone know the reason behind this and how I could fix this? Simply put, I want the desired image to be uploaded to "Add Photos" sections.
If anyone has a better solution to how approach the entirety of the problem, please let me know!
var convertToBase64 = function(url, imagetype, callback){
var img = document.createElement('IMG'),
canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'),
data = '';
// Set the crossOrigin property of the image element to 'Anonymous',
// allowing us to load images from other domains so long as that domain
// has cross-origin headers properly set
img.crossOrigin = 'Anonymous'
// Because image loading is asynchronous, we define an event listening function that will be called when the image has been loaded
img.onload = function(){
console.log('hoiii');
// When the image is loaded, this function is called with the image object as its context or 'this' value
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
console.log(canvas);
console.log(ctx);
data = canvas.toDataURL(imagetype);
console.log(data);
callback(data);
};
// We set the source of the image tag to start loading its data. We define
// the event listener first, so that if the image has already been loaded
// on the page or is cached the event listener will still fire
img.src = url;
console.log(img);
};
// Here we define the function that will send the request to the server.
// It will accept the image name, and the base64 data as arguments
var sendBase64ToServer = function(name, base64){
var httpPost = new XMLHttpRequest(),
path = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAFmklEQVRYR+1YWUiVaxRdx1nLOh7NynMpDbOOA4Z5pdvgQNFDb3VJIknqoVIQExyTNBHRCppoEkW0yVKQsMT7IBZGEZoiRaSlpSYOWM6m5HhZW4x75db5f4en24aDcv7z/Xt9a++99v4+zdTU1BTmaa9fv8a1a9fw9OlTTE5OwtvbGwEBAVi6dCl27NiBdevWzdmDZj4A29racPLkSTx48ABDQ0Pw9fXFnj174O/vj9HRUTx8+BAvXrzA3r17ERsbCxsbG9VA5wywtbUV8fHxKCwsxMTEBHbt2oXTp09j+/bt30F8/foVO3fuRGVlJY4cOYKUlBSsWbNGFcg5ARwfH0dCQgLOnz8vzjZt2oTs7GxhcLa9ffsWHh4e8vXhw4eRm5u7+ABLSkoQFhYGhpiWnp4uof6RkdX379/D3t4eOTk52Lp1q2KQc2IwNDQUt2/flpxiEWRmZsLZ2fmHTo8fP466ujp8+fIFBw4cQHJy8uIBZM6Rvd7eXlhaWuLWrVsIDg7+qcNLly4hPz9fcnXDhg3yv1JTzWBISIg40Ol00Gg0wooxe/78uRQQjarGql+2bJmxZfJcFcBPnz7Bx8cH3d3dsphs7t+/36ijd+/e4ejRo7C2tpZNJSUlYdu2bUbXqQZYUFCAY8eOYWBgAHZ2dqJxDJkxa2hoQHh4OExNTTE2NiY5GBgYaGyZegYPHTqEu3fvSpjo4MmTJ4qcEGBUVJSIN7WRerh7925Fa1WF2MvLC2/evJEXnzlzRoRaibGC4+LihHl2nIyMjMUB6OLigubmZixZsgQvX76EwWBQgg81NTUi7Kx8ivzVq1f/1XF+9hJVDFLrWlpapNdWVFQoAscfPX78WNgmwOXLl4uGuru7K1qvCiClpa+vD6dOnUJqaqoiB/wRZSU6OhqDg4My2bATrVixQtF6VQApERTnvLw86QhKjbp54sQJjIyMyChWXl4OKysrRcsVA7x48SJu3LghIaZksDsotaSkZFy+fFkY5GTj5/e70qXKhZoD6YULF/Dx40eZWmJiYsCqNpZLk5MAuw9FndrJoUGn0y48QDogC+wmXV1dMDc3l4k5Pj4BBw+GYOXK/86p4uJHspnGxkZs3rwZ1dVVisGp6iRpaWm4f/++dANWIwfWadMISIo4da6srAzV1dUiyNwAWbtz544MChwqCgruLTxA5g3Zo/bR+vv78fnz5+8AV61aLeMWi4AzIiudWunk5CRdh+wRaGJiIqKiIhce4Llz5+R8wSqmQ7LX2dkpYV6/3g39/QPo6emRyiQoMse2RtaampoEkJubmwyrBoPx3v3PHSiq4sjISBQXF8uASmbYrvjhhGxubgGeCwmIz8gkpYjFROY4HHBjLKaKCmW9WzXAs2fPCoOUCTMzM3z79k3CTIBk0MrKWkJOVrVaLfR6vQDu6OjAhw8fZJ2rqytevapVFV7FRcJmf+XKFZSWloqDGZAM5ZYtf2BwcOj7IEAhnjleEiDX8rN27Vr5a2KiDqOiEDOXsrKyRJwp1Gx5HD6Zj3r9b9Dp7KWF8dBuYmIiAy0ZJSB+x5zloFtTM11kakwRQL6QRcDTG4EyZDSCMRjcodXawdPTU6qYIaXEsGAoR5ymbW1tERERgfT0NDXYpkVMzc0Cc+z69evS/Nvb22V0IoOjo2NwcHAQUBzHmJ8sIj5nwfCQxQHDwUG3uABn3l5fXy/jflVVFfbt+xOlpX/h5s2bwtiMkV3mKK88eKug169WDU41g7M9PHv2TAbP1tbpOxqG1sLCAhs3bpTLIx6MLC3N5wRsZpGqEM/2NDw8jLq6ejg7u6C2thZBQUEwNdVgfHwSZmYqy/UH25gXQL7z0aMS+Pn5gXcwQUHKTmpqKJ03wKKiIjg6OsqtFbVuoe0XwPky+ovBXwwaY+B/X8V/A+fXNLaIW65OAAAAAElFTkSuQmCC",
data = JSON.stringify({image: base64});
httpPost.onreadystatechange = function(err) {
if (httpPost.readyState == 4 && httpPost.status == 200){
console.log(httpPost.responseText);
} else {
console.log(err);
}
};
// Set the content type of the request to json since that's what's being sent
httpPost.open("POST", path, true);
httpPost.setRequestHeader('Content-Type', 'image/jpeg');
httpPost.send(data);
};
// This wrapper function will accept the name of the image, the url, and the
// image type and perform the request
var uploadImage = function(src, name, type){
convertToBase64(src, type, function(data){
sendBase64ToServer(name, data);
});
};
// Call the function with the provided values. The mime type could also be png
// or webp
uploadImage(result.products[pointer][3], 'cool.jpeg', 'image/jpeg');
So, I have a user input which serve to upload pictures. This is a simple example:
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
console.log (img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<input type="file" onchange="handleImage(event)"><br>
As you can see, I display an Image () on the console. I want to convert this Image into a jpg file.
I understood how to get the pixels of the picture but it's completely crazy to send it to a server: It's to large!
I also tried to access to the jpg file stored in the computer but I do not achieve to anything.
The only way I found is to send it with a form like this:
<form action="anything.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
And in PHP:
$_FILES["fileToUpload"]["tmp_name"]
Why not with JS?
My final goal is to send the jpg file with AJAX.
Tell me if you have some questions.
The simplest way is to use a canvas element and then invoke a download action allowing the user to select where to save the image.
You mention that the image is large, but not how much - be aware that with canvas you will also run into restrictions when the image source starts to touch around the 8k area in pixel size.
A simplified example (IE will require a polyfill for toBlob()).:
Load image source via input
Use File blob directly as image source via URL.createObjectURL()
When loaded, create a temporary canvas, set canvas size = image size and draw in image
Use toBlob() (more efficient on memory and performance and require no transcoding to/from Base64) to obtain a Blob.
We'll convert the Blob to File (a subset object and it will reference the same memory) so we can also give a filename as well as (important!) a binary mime-type.
Since the mime-type for the final step is binary the browser will invoke a Save as dialog.
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
c.toBlob(function(blob) {
var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
window.location = URL.createObjectURL(file);
}, "image/jpeg", 0.75); // mime=JPEG, quality=0.75
}
// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>
Update: If you just are after a string (base-64 encoded) version of the newly created JPEG simply use toDataURL() instead of toBlob():
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
var jpeg = c.toDataURL("image/jpeg", 0.75); // mime=JPEG, quality=0.75
console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>
JavaScript on the client side can not save files.
You have multiple options:
Render the image on an <canvas> element. This way it can be saved with right click -> save image
Inset the image as <img> element. This way it can be saved with right click -> save image
Send the image data as base64 string to the server. Do the processing there
Use a server side language like PHP or Node.js to save the file
Long story short, you have to use some server side logic to save the file on disk
I want a valid string of base64 from imageuri. I have use below code for this but it's getting black image after uploading it to the server.
function encodeImageUri(imageUri)
{
var c=document.createElement('canvas');
var ctx=c.getContext("2d");
var img=new Image();
img.onload = function(){
c.width=this.width;
c.height=this.height;
ctx.drawImage(img, 0,0);
};
img.src=imageUri;
var dataURL = c.toDataURL("image/jpeg");
return dataURL;
}
I have also tried other options but not getting solid solution to get the valid base64 imagedata. I don't want to upload image using file-transfer method. I want to convert the imageuri in simple base64 string. Please suggest me specific answer for the same.
Thanks
Please note that I've not tested this within PhoneGap.
It's possible you're being caught out by the image being loaded asynchronously; you're encoding it into a string before it's actually loaded and processed in full.
There are various ways of handling this; one possibility is to move to using a success() method to handle the return value, which will be called once the image has loaded and been drawn:
function encodeImageUri(imageUri, success)
{
var c=document.createElement('canvas');
var ctx=c.getContext("2d");
var img=new Image();
img.onload = function(){
c.width=this.width;
c.height=this.height;
ctx.drawImage(img, 0,0);
success(c.toDataURL("image/jpeg"));
};
img.src=imageUri;
}
You will then need to call encodeImageUri with a function that will handle the end result, for example:
encodeImageUri(" < url > ", function (data) {
console.log(data);
});
Depending upon the security model PhoneGap uses, you may have to look out for CORS-related issues (see Tainted canvases may not be exported).
I have a function that encodes an image into base64 string and stores it into localStorage. I am trying to retrieve the image from localStorage and use it to set a background-image with jQuery.
Everything is working right, but the image isn't displaying. When I inspect the element in the browser, the single quotes around the 'data' uri aren't being inserted. I don't know if this is the problem or not.
Here is my code
function to encode and store image:
var img = document.getElementById("elephant");
function getBase64Image(img) {
// Create an empty canvas element
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// Copy the image contents to the canvas
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// Get the data-URL formatted image
// Firefox supports PNG and JPEG. You could check img.src to
// guess the original format, but be aware the using "image/jpg"
// will re-encode the image.
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
return dataURL;
}
jQuery to set the image:
localStorage.setItem("background" , getBase64Image(img));
console.log(localStorage);
background = localStorage.getItem("background")
console.log(background);
$("#elephant2").css('background-image' , 'url(' +background+ ')');
I thought the issue was missing quotes, but it was actually corrupted/incomplete base64 data string. I placed the function inside window.onload = function () so the image loaded entirely before converting to a string and it works like a charm/
I have create upload file , but I have stack when I want to validation that content is image or not, because if validate extension only we can manipulate with fake content and valid extension.
is there function similar getimagesize() php in javascript?
In some of the more modern browsers you can load an image into a canvas context (this doesn't actually have to be displayed on the page) and get the dimensions from that.
I did something like this in a CMS I built to allow the image to be scanned for certain colours without it having to be uploaded to a server first:
$('section.content form input[name=image]').change(function(){
file = this.files[0];
if(file.type.match(/image.*/))
{
var img = document.createElement('img');
// add this into an onload, as it takes time (albeit very little) to load the image into the DOM object
img.onload = function(){
canv = document.getElementById('product_image');
if(!canv || !canv.getContext)
return; // problem getting the canvas element
// get the canvas context that we'll be using and the width of the canvas & image
var ctx = canv.getContext('2d');
var width = img.width;
var height = img.height;
};
// put the file into the img object, triggering the img onload handler above
var reader = new FileReader();
reader.onload = function(e) {img.src = e.target.result};
reader.readAsDataURL(file);
}
});