javascript load image from local hard drive using blob - javascript

The following code should be able to save and load .png image to/from local hard drive.
Saving works fine(at least in chrome) but loading produces wrong url and display nothing..
A little help would be really appreciated!
<html>
<head>
<title></title>
</head>
<body>
<img id="img" /><br>
<input type="button" value="Save" onclick="onSave()" /><br />
<input type="file" onchange="onOpen(event)" /><br />
<script>
onSave = function () {
var canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, 100, 150);
var dataURL = canvas.toDataURL("image/png");
var img64 = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
var binaryImg = atob(img64);
var length = binaryImg.length;
var ab = new ArrayBuffer(length);
var ua = new Uint8Array(ab);
for (var i = 0; i < length; i++) {
ua[i] = binaryImg.charCodeAt(i);
}
var blob = new Blob([ab]);
var a = document.createElement("a");
a.download = 'Blob_img';
a.innerHTML = "Download File";
a.href = window.webkitURL.createObjectURL(blob);
a.style.display = 'none';
document.body.appendChild(a);
a.click();
};
onOpen = function (event) {
var fileReader = new FileReader();
fileReader.onload = function (event) {
var ab = event.target.result;
var ua = new Uint8Array(ab);
var binaryImg;
for (var i = 0; i < ua.length; i++) {
binaryImg += String.fromCharCode(ua[i]);
}
var img64 = btoa(binaryImg);
var image = new Image();
image.src = 'data:image/png;base64,' + img64;
var img = document.getElementById('img');
img.src = image.src;
}
fileReader.readAsArrayBuffer(event.target.files[0]);
};
</script>
</body>
</html>

Your "load" handler for your FileReader is declared without an event parameter. As a result, it's not going to have access to the file contents.
fileReader.onload = function (event) {
var ab = event.target.result;
Without that parameter, the symbol "event" would refer to the parameter of the enclosing function, and that one won't have the file contents.
Also, I think you don't need to do the base64 encoding/decoding via atob and btoa, because the results of converting the canvas contents to a data URL will be a base64 string anyway.

In case somebody is wondering, there is a simpler way of reading the file:
FileReader.readAsDataURL
Check a working example at https://developer.mozilla.org/en-US/docs/Web/API/FileReader.readAsDataURL.

Related

msSaveBlob does not return the full image

I am trying to implement a download button for Internet Explorer users that will let them download a png file being displayed on a page.
The image is provided as a Data URL and displays normally on the page.
However, when the image is downloaded on Internet Explorer using the following code, only the upper half of the image gets downloaded.
I know the problem does not come from dataURLtoBlob() because reading the blob as a Data Url returns exactly the same original data.
Can anyone help me understand what's going on here? Thanks a lot for the help.
downloadButton.onclick = function () {
if (window.navigator.msSaveOrOpenBlob) {
var filename = "image.png";
var data = $('#qrCode').attr("href");
var blob = dataURLtoBlob(data);
console.log(data);
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function() {
console.log(reader.result);
};
window.navigator.msSaveBlob(blob, filename);
}
}
function dataURLtoBlob(dataUrl) {
var arr = dataUrl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var byteString = atob(arr[1]);
var arrayBuffer = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mime });
}
I managed to find a workaround for this issue by using an intermediate canvas.
var ieCanvas = document.getElementById("ieCanvas");
var ctx = ieCanvas.getContext("2d");
var img = document.getElementById("qrCodeImg");
ctx.drawImage(img, 0, 0);
var filename = "download.png";
window.navigator.msSaveBlob(ieCanvas.msToBlob(), filename);
To summarise:
QR Code PNG -> Blob -> msSaveBlob = Half of the image
QR Code PNG -> Canvas -> Blob -> msSaveBlob = Full image

Blob image returns blank image

I'm trying to extract image information from canvas data and display it in a .png file. Thus far I've been able to extract the Base64 information from the canvas using the toDataURL() method and create a blob object (which is correctly identified as a .png image) but the image is always blank. Any suggestions? Here's the code
var canvasData = markup.find('canvas');
var imageDataURL = canvasData[4].toDataURL("image/png");
var theData = atob(imageDataURL.substring('data:image/png;base64,'.length)), asArray = new Uint8Array(theData.length);
for (var i = 0, len = theData.length; i < len; ++i) {
asArray[i] = theData.charCodeAt(i);
}
var blob = new Blob([asArray.buffer], { type: 'image/png' }); saveAs(blob, 'export_' + Date.now() + '.png');
Interestingly the size is correct, the only thing missing is the actual image within the .png.
Assuming the saveAs function initiates a file download, you can take a shortcut by just assigning the data URL to an a element, set a.download to the desired file name, and using a.click() to start the file download:
function canvasToFile()
{
var canvas = document.getElementsByTagName('canvas')[0];
canvas.getContext("2d").drawImage(img, 0, 0);
var a = document.createElement('a');
a.href = canvas.toDataURL("image/png");
a.download = 'export_' + Date.now() + '.png';
a.style.display = 'none';
document.body.appendChild(a);
a.click();
}
// For demo:
var img = document.getElementsByTagName('img')[0];
img.crossOrigin = 'Anonymous';
img.addEventListener('load', canvasToFile);
img.src = 'http://lorempixel.com/400/400/';
<canvas width="400" height="400"/>
<img/>
In some browsers it is not necessary to append a to the DOM tree (hence the lines a.style.display = 'none'; and document.body.appendChild(a); could be omitted), but in others (Firefox for example, if I'm not mistaken) it is.

How can we upload multiple html files and replace the text inside and get the output html pages with the help of javascript

From following code it accepts Single File and process it & display output.but can it be possible to accept multiple files and process & then return output.
<html>
<head>
</head>
<body>
<div>
<label for="text">Choose file</label>
<input id="text" type="file" name="photo">
</div>
<textarea id="finalHTML" style="height:200px;width:80%">
</textarea><br/>
<button id="save">Save</button>
<script>
$('input').change(function(){
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(e);
selectedImage = e.target.result;
var rawData = reader.result;
console.log(rawData);
var array = {
'<code CLASS="java">j</code>':'⇔',
'<code CLASS="bold">C</code>':'<b>C</b>',
'<code CLASS="italic">g</code>':'œ',
'<code CLASS="underline">i</code>':'~',
}
var originalText = rawData.toString();
var finalText = originalText;
for (var val in array)
finalText = finalText.replace(new RegExp(val, "g"), array[val]);
console.log(finalText);
$('#finalHTML').text(finalText);
};
reader.readAsBinaryString(this.files[0]);
//reader.readAsDataURL(this.files[0]);
}
});
var button2 = document.getElementById('save');
button2.addEventListener('click', saveTextAsFile);
function saveTextAsFile()
{
var textToWrite = $('#finalHTML').text();
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = "sample1.html"/*Your file name*/;
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
</script>
</body>
</html>
I am not able to accept multiple files and process on it,and return Output.
Any one can help me out please.
You used input type 'file' there is an attribute multiple ="multiple" which allows you to select multiple file at once. How to handle those files using JavaScript? you can look at this link ...Multiple-files-selected
try this and look at the for loop block... I'm not tasted it...
$('input').change(function(){
for(var i = 0; i<= files.length; i++){
if (this.files && this.files[i]) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(e);
selectedImage = e.target.result;
var rawData = reader.result;
console.log(rawData);
var array = {
'<code CLASS="java">j</code>':'⇔',
'<code CLASS="bold">C</code>':'<b>C</b>',
'<code CLASS="italic">g</code>':'œ',
'<code CLASS="underline">i</code>':'~',
}
var originalText = rawData.toString();
var finalText = originalText;
for (var val in array)
finalText = finalText.replace(new RegExp(val, "g"), array[val]);
console.log(finalText);
$('#finalHTML').text(finalText);
};
reader.readAsBinaryString(this.files[i]);
//reader.readAsDataURL(this.files[0]);
}
}
});

Javascript: prepare image object for FileReader readAsBinaryString

I'm currently following this tutorial for uploading images to Google Drive from javascript. The example code works perfectly in that you can select a file to upload from your hard drive. I'm now trying to modify it for my purposes so that it instead uploads an image already displayed on the page in standard HTML form:
<img class="image" id="result-image" src="imgres?img_id={{result_id}}" alt="No Image"/>
The supplied Google example looks for a change on the file selector and gets the file data as follows:
var fileData = evt.target.files[0];
Which is then read by a FileReader object as follows:
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
...
My question is how do I supply the image object tag in the required type for the FileReader readAsBinaryString method so that the Drive API calls can succeed? Thanks in advance!
Fixed using Joe Coder's solution as follows:
var img = document.getElementById('result-image');
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
var dataUrl = canvas.toDataURL('image/png');
var blob = dataUriToBlob(dataUrl);
var reader = new FileReader();
reader.readAsBinaryString(blob);
reader.onload = function(e) {
...
With dataUriToBlob method:
function dataUriToBlob(dataURI) {
// serialize the base64/URLEncoded data
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
}
else {
byteString = unescape(dataURI.split(',')[1]);
}
// parse the mime type
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// construct a Blob of the image data
var array = [];
for(var i = 0; i < byteString.length; i++) {
array.push(byteString.charCodeAt(i));
}
return new Blob(
[new Uint8Array(array)],
{type: mimeString}
);
}

How to convert an image to base64 in JavaScript

I'm trying to write a file upload script for use in a secure corporate intranet and having just a little trouble...
In the following code, I get no errors and all my debugging looks like everything is working, but the end result is always a 'blank' image:
var ctx = document.createElement('canvas');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
}
img.src = $('#UpdateImage:file');
var imgStr = ctx.toDataURL("image/png", "");
document.getElementById("Item_Create_Image_Avatar").src = imgStr;
When I "inspect element" on the 'Item_Create_Image_Avatar' object, the 'src' value looks absolutely perfect:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAEYklEQVR4Xu3UAQkAAAwCwdm/9HI83BLIOdw5AgQIRAQWySkmAQIEzmB5AgIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlACBB1YxAJfjJb2jAAAAAElFTkSuQmCC" id="Item_Create_Image_Avatar" style="vertical-align:top">
Why is my image coming in as blank?
Found This.
Select a File to Load:
<input id="inputFileToLoad" type="file" onchange="loadImageFileAsURL();" />
<div id="imgTest"></div>
<script type='text/javascript'>
function loadImageFileAsURL(){
var filesSelected = document.getElementById("inputFileToLoad").files;
if (filesSelected.length > 0){
var fileToLoad = filesSelected[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
var srcData = fileLoadedEvent.target.result; // <--- data: base64
var divTest = document.getElementById("imgTest");
var newImage = document.createElement('img');
newImage.src = srcData;
divTest.innerHTML = newImage.outerHTML;
}
fileReader.readAsDataURL(fileToLoad);
}
}
</script>
EDIT:
Source: How to convert image into base64 string using javascript
If you want to get the Data URL of the image after it loaded, you should get the Data URL after it loaded
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
imgStr = canvas.toDataURL("image/png", "");
document.getElementById("Item_Create_Image_Avatar").src = imgStr;
}
img.src = $('#UpdateImage:file');
EDIT: Included the rest of the code
EDIT2: Edited stupid error regarding canvas and its context

Categories

Resources