I want to export the jpeg image from svg using blob. This working fine in chrome. But, my sample is not working safari browser(MAC).
Can you please tell how to resolve this? wheather blob is support in IOS or not?
while run this sample in ios thrown image load error.
Sample Link: http://jsfiddle.net/kyjs655r/363/
document.getElementById('export').onclick = function () {
var tag = document.getElementById('export');
tag.download = 'Sample' + "." + 'png';
tag.href = getCanvaElement().toDataURL();
}
function getCanvaElement() {
var svgText = document.getElementById("myViewer").outerHTML;
var svg = new Blob([svgText], { type: "image/svg+xml;charset=utf-8" });
var domURL = self.URL || self.webkitURL || self;
var url = domURL.createObjectURL(svg);
var element = document.createElement('canvas');
var ctx = element.getContext("2d");
var image = new Image;
image.onload = function () {
ctx.drawImage(this, 0, 0);
domURL.revokeObjectURL(url);
};
image.onerror = function () {
alert();
};
image.src = url;
return element;
}
Related
I am trying to export my chart data consisting of image and data in a PDF. It works fine for me in laptop browser, but while I am trying to do the same in Ipad, the img.onload() function is not firing. I am not sure but I feel like it is due to the size of the image that is rendering in it. Can anybody help me with it? Can we change the pixels of the image that is being rendered?
The code is given below:-
function exportData(exportType) {
if (exportType) {
if (exportType == "pdf") {
alert("clicked pdf")
console.log("pdf export ....")
vm.toggleCanvas = !vm.toggleCanvas;
var canvas = "";
var ctxt = "";
// var img = "";
var sheets = "";
var svgURL = "";
canvas = document.getElementById('canvas');
$log.log($window.screen.width)
//resizing image for PDF
if ($window.screen.width >= 1500) {
canvas.width = $window.screen.width - 150;
} else {
canvas.width = $window.screen.width;
}
console.log("before canvas")
ctxt = canvas.getContext('2d');
sheets = document.styleSheets;
svgURL = generateSVGWithStyling('svg');
// var img = document.createElement('img');
var img = new Image();
console.log("after image")
console.log(img)
alert("imb")
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgURL);
img.onload = function () {
debugger
console.log("in load")
alert("in load")
ctxt.drawImage(this, 0, 0);
vm.cnvasImg = "";
vm.cnvasImg = canvas.toDataURL();
var content = "";
console.log("on load")
subExportData(vm.cnvasImg, exportType);
}
console.log(img.src)
} else {
vm.cnvasImg = "nothing";
subExportData(vm.cnvasImg, exportType);
}
}
}
Any help would be apprciated.
Can you please try with passing the width, height properties to Image constructor Object.
var img = new Image(Width, Height);
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have tried to export the png image from svg element using Blob. Here, when i click the anchor tag the image has been exported but there is no content because of asynchronous method(image.onload()) called after complete the click event. How to resolve this problem?
<body>
<a id="export">Click To Export</a>
<div id="container" width=500px height=200px>
<svg id="myViewer" width="500px" height="200px" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="20" width="150" height="150" style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9"
/>
</svg>
</div>
<script>
document.getElementById('export').onclick = function () {
var tag = document.getElementById('export');
tag.download = 'Sample' + "." + 'png';
tag.href = getCanvaElement().toDataURL();
}
function getCanvaElement() {
var svgText = document.getElementById("myViewer").outerHTML;
var svg = new Blob([svgText], { type: "image/svg+xml;charset=utf-8" });
var domURL = self.URL || self.webkitURL || self;
var url = domURL.createObjectURL(svg);
var element = document.createElement('canvas');
var ctx = element.getContext("2d");
var image = new Image;
image.onload = function () {
ctx.drawImage(this, 0, 0);
domURL.revokeObjectURL(url);
};
image.src = url;
return element;
}
</script>
</body>
Sample Link: http://jsfiddle.net/kyjs655r/347/
You can use Promise constructor and async/await, resolve() <canvas> element within <img> load event
document.getElementById('export').onclick = async function() {
var tag = document.getElementById('export');
tag.download = 'Sample' + "." + 'png';
const canvas = await getCanvaElement();
tag.href = canvas.toDataURL();
}
function getCanvaElement() {
return new Promise(resolve => {
var svgText = document.getElementById("myViewer").outerHTML;
var svg = new Blob([svgText], {
type: "image/svg+xml;charset=utf-8"
});
var domURL = self.URL || self.webkitURL || self;
var url = domURL.createObjectURL(svg);
var element = document.createElement('canvas');
var ctx = element.getContext("2d");
var image = new Image;
image.onload = function() {
ctx.drawImage(this, 0, 0);
domURL.revokeObjectURL(url);
resolve(element)
};
image.src = url;
})
}
jsfiddle http://jsfiddle.net/kyjs655r/351/
I have a php file "linkToThePhpFileHere.php". It creates a QR Code and returns something like that:
https://i.stack.imgur.com/y7zHA.png
That's how I display the code:
<div style="background-image: url(linkToThePhpFileHere.php);"></div>
But I want to store the content of "linkToThePhpFileHere.php" in an array in the local storage of the browser and I think, it's not a good idea to save the binary code there?
Is it possible to use Javascript/Jquery to load and convert the cotent of my file. It should look like this: https://i.stack.imgur.com/soYPr.png and be saved in a var:
var str = convertToSth($.get("linkToThePhpFileHere.php"));
var str = convertToSth($.get("linkToThePhpFileHere.php"));//this should be in base64
localStorage.setItem("imgData", str );
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
function getImage(imageUrl, callback) {
var img = document.createElement("img");
img.setAttribute('crossOrigin', 'anonymous');
img.src = imageUrl;
img.onload = function() {
var str = getBase64Image(img);
if (typeof callback == "function") callback(str);
}
}
getImage('https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg',function(imgData){
localStorage.setItem("imgData1", str );
})
getImage('linkToThePhpFileHere.php',function(imgData){
localStorage.setItem("imgData1", str );
})
You can store data URI representation of image in localStorage
window.onload = () => {
if (localStorage.getItem("image") === null) {
fetch("linkToThePhpFileHere.php")
.then(response => reponse.blob())
.then(blob => {
const reader = new FileReader;
reader.onload = () {
localStorage.setItem("image", reader.result);
document.querySelector("div")
.style.backgroundImage = "url(" + reader.result + ");";
}
reader.readAsDataURL(blob)
})
} else {
document.querySelector("div")
.style.backgroundImage = "url(" + localStorage.getImage("image") + ")";
}
}
I am trying to make it work for the past 2 days, went through every article that I came across regarding this issue but I just can't seem to make it work in Safari. The code works flawlessly in Firefox and Chrome but when I test it in Safari, it always disappoints me. I am trying to do the following:
for (var j = 0; j < total_reports; j++) {
var svgString = $(elem_graph).find('svg');
$(svgString)[0].setAttribute('width','2500');
$(svgString)[0].setAttribute('height','500');
$(svgString)[0].setAttribute('viewBox', '0 0 1000 200');
$(svgString)[0].setAttribute('preserveAspectRatio', 'none');
$(elem_graph).find("span").html();
var img = new Image();
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
var svgString = $(elem_graph).find('svg');
$(svgString)[0].setAttribute('width','2500');
$(svgString)[0].setAttribute('height','500');
$(svgString)[0].setAttribute('viewBox', '0 0 1000 200');
$(svgString)[0].setAttribute('preserveAspectRatio', 'none');
svgString=$(elem_graph).find("span").html();
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = (function(img) {
return function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var png = canvas.toDataURL("image/png");
pdf.addImage(png, 'PNG', 10, 120, 485, 270);
pdf.addPage();
DOMURL.revokeObjectURL(png);
pdf.save("test.pdf");
img_load_counter++;
canvas = null;
ctx = null;
png = null;
}
})(img);
img.src = url;
svgString = null;
svg=null;
unformatSvgString = null;
url=null;
}
It works fine until it reaches "img.onload = (function(img)" it just does not registers the load event for img. I also tried addEventListener() but it doesn't seem to work either.
Also, the closure, "canvas = null;
ctx = null;
png = null;" doesn't seem to free any memory at all, any solutions for that are also welcomed.
Maybe too late but I hope it helpful for other people.
You can change:
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
with:
url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent( svgString );
We are building an application where the user can upload images, but I need to resize an image before I can upload them to the server. The input for the file is an input[type=file] and we check if the image is valid. If it is valid, we continue with the following request:
Upload.upload({url: url, data: {file: input.x}, headers: {'Authorization': token}});
The input variable is the value of the input field in the HTML. This codes works great when we don't need to resize the image. Unfortunately, this would only be the case in a perfect world. After a while searching for the same problems, I seem to have found the solution using the following function:
var resize = function(size, url, callback) {
var temp = new Image();
temp.onload = function() {
var target = { width: temp.width, height: temp.height, aspect: temp.width / temp.height };
if (temp.width > temp.height) {
size = Math.min(temp.width, size);
target.width = size; target.height = size / target.aspect;
} else {
size = Math.min(temp.height, size);
target.height = size; target.width = size * target.aspect;
}
var canvas = document.createElement('canvas');
canvas.width = target.width; canvas.height = target.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, temp.width, temp.height, 0, 0, target.width, target.height);
callback(canvas.toDataURL(url.split(',')[0].split(':')[1].split(';')[0]));
}; temp.src = url;
}
This appears to be working great. I need to pass a Base64 string. So I wrapped the upload method inside the following:
var reader = new FileReader();
reader.onload = function(e) {
resize(1000, e.target.result, function(done) {
console.log(done);
Upload.upload({url: url, data: {file: done}, headers: {'Authorization': UserService.getToken()}});
});
}
reader.readAsDataURL(file);
This way I pass a Base64 string containing the image and even this seems to be working like a charm. But the biggest problem is, the server expects a real file and not a Base64 string. So the upload itself fails.
I found the function on Convert Data URI to File then append to FormData which should fix this, but it doesn't. I changed the method to this after adding the method from the link:
var reader = new FileReader();
reader.onload = function(e) {
resize(1000, e.target.result, function(done) {
console.log(done);
Upload.upload({url: url, data: {file: dataURItoBlob(done)}, headers: {'Authorization': UserService.getToken()}});
});
}
reader.readAsDataURL(file);
Does any of you know how I could change the Base64 string back to a file again? I found tons of post explaining how I could show them in a browser, but none solving my problem to upload it as file.
Sorry for the question. But it seems the dataURItoBlob function works fine, but there is was no original filename inside the blob, so I couldn't upload it right away. I changed the resize function so it performs both actions at once and this is the result:
var resize = function(size, url, name, callback) {
var temp = new Image();
temp.onload = function() {
var target = { width: temp.width, height: temp.height, aspect: temp.width / temp.height };
if (temp.width > temp.height) {
size = Math.min(temp.width, size);
target.width = size; target.height = size / target.aspect;
} else {
size = Math.min(temp.height, size);
target.height = size; target.width = size * target.aspect;
}
var canvas = document.createElement('canvas');
canvas.width = target.width; canvas.height = target.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, temp.width, temp.height, 0, 0, target.width, target.height);
var type = url.split(',')[0].split(':')[1].split(';')[0];
var data = canvas.toDataURL(type);
//callback(data);
var bytes = (data.split(',')[0].indexOf('base64') >= 0) ? atob(data.split(',')[1]) : unescape(dataURI.split(',')[1]);
var ia = new Uint8Array(bytes.length);
for(var i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); }
var blb = new Blob([ia], {type : type});
blb.name = name;
callback(blb);
}; temp.src = url;
};
To upload the file, I do the following:
var deferred = $q.defer();
var reader = new FileReader();
reader.onload = function(e) {
resize(maxSize, e.target.result, image.name, function(done) {
deferred.resolve(Upload.upload({url: url, data: {file: done}, headers: {'Authorization': token}));
});
}
reader.readAsDataURL(image);
return deferred.promise;