Load image into FileReader - javascript

I want to load an image from an url into filereader in order to obtain a data url of that image. I tried to search for the solution on google but i can only find solutions to read them from the file input on a local computer.

If you want a usable data-URI representation of the image, then I suggest to load the image in a <img> tag, paint it on a <canvas> then use the .toDataURL() method of the canvas.
Otherwise, you need to use XMLHttpRequest to get the image blob (set the responseType property on the XMLHttpRequest instance and get the blob from the .response property). Then, you can use the FileReader API as usual.
In both cases, the images have to be hosted on the same origin, or CORS must be enabled.
If your server does not support CORS, you can use a proxy that adds CORS headers. In the following example (using the second method), I'm using CORS Anywhere to get CORS headers on any image I want.
var x = new XMLHttpRequest();
x.open('GET', '//cors-anywhere.herokuapp.com/http://www.youtube.com/favicon.ico');
x.responseType = 'blob';
x.onload = function() {
var blob = x.response;
var fr = new FileReader();
fr.onloadend = function() {
var dataUrl = fr.result;
// Paint image, as a proof of concept
var img = document.createElement('img');
img.src = dataUrl;
document.body.appendChild(img);
};
fr.readAsDataURL(blob);
};
x.send();
The previous code can be copy-pasted to the console, and you will see a small image with YouTube's favicon at the bottom of the page. Link to demo: http://jsfiddle.net/4Y7VP/

Alternative download with fetch:
fetch('http://cors-anywhere.herokuapp.com/https://lorempixel.com/640/480/?
60789', {
headers: {},
}).then((response) => {
return response.blob();
}).then((blob) => {
console.log(blob);
var fr = new FileReader();
fr.onloadend = function() {
var dataUrl = fr.result;
// Paint image, as a proof of concept
var img = document.createElement('img');
img.src = dataUrl;
document.body.appendChild(img);
};
fr.readAsDataURL(blob);
}).catch((e) => console.log(e));

Related

How to Convert image URL from server (API / ImageURL) to Base64 in Vue.Js

A lot of reference I see about this problem is about upload file and convert to base64 but in my case I want to convert an Image URL from server and convert it to base64 but I still failed to do it, right now I tried it like this, but it still failed since it doesn't show anything
this is my html:
<div v-if="questionData">
<img class="img-preview-download" :src="questionData.image_url? getBase64Image(questionData.image_url) : 'https://via.placeholder.com/640x360'" alt="img-preview">
</div>
this is my method:
getBase64Image(img) {
console.log("cek base64 : ", btoa(img));
return `data:image/jpeg;base64,${btoa(img)}`;
},
I read some using file reader but isn't it only for file when you upload a data using input? can someone help me to solve this? I'm using Vue.Js for the framework
when I used this method I got result like this:
So this is my answer for my future self, who might be forget and stumble again in this problem!
You can solve it by making a new image and inside that image file, you can add your src so the image can be process when still loading or onload.
Remember!
Since it is you, You might be remove the last image.src = url to get a clean code, but this is important, if you remove that line, image.onload will not be trigger because it will search for the image source. and if you try to use image.srcObject to put it with mediaStream it will give you Resolution Overloaded since you still not find the answer for this problem, it is okay, you can use the image first since your step is to achieve how to get file from Image URL. so this is the method you use to solve this problem:
downloadPreview() {
const el = this.$refs.printMe;
const options = {
type: 'dataURL'
};
this.$html2canvas(el, options).then(data => {
this.output = data;
const a = document.createElement('a');
a.style.display = 'none';
a.href = data;
// this is just optional function to download your file
a.download = `name.jpeg`;
document.body.appendChild(a);
a.click();
});
},
convertImgUrlToBase64(url) {
let self = this;
var image = new Image();
image.setAttribute('crossOrigin', 'anonymous'); // use it if you try in a different origin of your web
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext('2d').drawImage(this, 0, 0);
canvas.toBlob(
function(source) {
var newImg = document.createElement("img"),
url = URL.createObjectURL(source);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
},
"image/jpeg",
1
);
// If you ever stumble at 18 DOM Exception, just use this code to fix it
// let dataUrl = canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
let dataUrl = canvas.toDataURL("image/jpeg");
console.log("cek inside url : ", url);
if(url === backgroundImg) {
self.assignImageBase64Background(dataUrl);
} else {
self.assignImageBase64(dataUrl);
}
};
image.src = url;
},
assignImageBase64(img) {
this.imgBase64 = img;
},
just for information, I use this library to change the div into image file:
vue-html2canvas
Notes:
If you ever wondering why I give self.assignImageBase64(dataUrl); this function in the end, this is because I still wondering how onload works, and how to return Base64 url to the parent thats why I just assign it again in another function since it easier to do.

ArrayBuffer to jpeg

I am streaming ArrayBuffers from a python server and am trying to interpret each one as an image on the client side with javascript. They are being received as arraybuffers in javascript. However I cant get them to be readable by the image tags src attribute. I have tried generating them into Blob objects then using window.URL.createObjectURL(blob). That hasnt work either.
The blob url looks like this blob:null/e2836074-64b5-4959-8211-da2fc24c35a6 is that wrong?
Does any have any suggestions/know a solution.
Thanks a lot.
var arrayBuffer = new Uint8Array(stream.data);
var blob = new Blob([arrayBuffer], {type: "image/jpeg"});
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
console.log(imageUrl);
img.src = imageUrl;
array buffer image
If you have any control over things, you should use the responseType of blob on your Javascript call. This will let you use the data you are getting from your server directly instead of attempting to access it via an ArrayBuffer
See the following fiddle for an example: https://jsfiddle.net/ort74gmp/
// Simulate a call to Dropbox or other service that can
// return an image as a blob
var xhr = new XMLHttpRequest();
// Use JSFiddle logo as a sample image to avoid complicating
// this example with cross-domain issues.
xhr.open( "GET", "https://fiddle.jshell.net/img/logo.png", true );
// Ask for the result as an ArrayBuffer.
xhr.responseType = "blob";
xhr.onload = function( e ) {
var blob = this.response;
var reader = new FileReader();
reader.onload = function() {
var dataURL = reader.result;
document.querySelector('#photo').src = dataURL;
}
reader.readAsDataURL(blob);
};
xhr.send();

Blob image from database to Java and from Java to Javascript Image

I have Blob, which stored in db and i take it from database with java server like this:
Entity.java
#Column(name = "img")
private Blob img;
public Blob getImg() {
return img;
}
public void setImg(Blob img) {
this.img = img;
}
Repository.java
#Transactional
#Query(value = "SELECT img FROM articles WHERE category = ?", nativeQuery = true)
//Blob findP(String category);
Blob findPic(String category);
Controller.java
#RequestMapping(value="/Pic_test")
#ResponseBody
public Blob getPics() throws SQLException, IOException {
return remindRepository.findPic("Java");
}
Then I receive it with Javascript to image it:
function toDataURL(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
toDataURL('http://localhost:8080/articles/Pic_test', function(dataUrl) {
var display = document.getElementById('display');
var url = window.URL.createObjectURL(new Blob([dataUrl]));
var img = new Image();
img.src = url;
document.getElementById("demo").innerHTML = img.src;
})
However, if I call my "img" Blob in java code, i have an error in server, but if I call it byte[], my picture is not shown just.
I can't comment the java part since I know nothing about it, but for the javascript one, what you do is... not correct.
You don't seem to understand what is a data URL, nor what you are doing here.
So a data URL is a string, made of an header and of some file content (data:|mime/type;|file-content).
A data URL is an URL that points to itself, useful to embed data that should normally be served from network.
Quite often, the file content part is encoded as base64, because the URI scheme is limited in its set of allowed characters, and that binary data couldn't be represented in this scheme.
Now let's see what you are doing here...
You are downloading a resource as a Blob. That's good, Blob are perfect objects to deal with binary data.
Then, you read this Blob a data URL. Less good, but I can see the logic, <img> can indeed load images from data URLs.
But then from this data URL string, you create a new Blob! This is completely wrong. The Blob you just created with new Blob([dataUrl]) is a text file, not your image file in any way. So yes, the data is still hidden somewhere in the base64 data which is itself in the data URL, but what your poor <img> will see when accessing the data hooked by the Blob URI is really just text, data:image/png;base64,iVBORw0... and not at all �PNG... like its parsing algo can read.
So the solution is quite easy: get rid of the FileReader step. You don't need it.
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png');
xhr.responseType = 'blob';
xhr.onload = display;
xhr.send();
function display(evt) {
// we did set xhr.responseType = "blob"
var blob = evt.target.response; // so this is a Blob
// hence, no need for anything else than
var url = URL.createObjectURL(blob);
var img = new Image();
img.src = url;
document.body.appendChild(img);
}
And if I may, all your thing could also just be
document.getElementById('display').src = 'http://localhost:8080/articles/Pic_test';

Get base64 of an image

I am trying to get base64 of the image in my HTML by using HTML FileReader but for some reasons it doesn't work. My html is:
<div></div>
And script is:
var file = "http://mw2.google.com/mw-panoramio/photos/medium/23830229.jpg";
var reader = new FileReader();
reader.onload = function (e) {
iconBase64 = e.target.result;
$('div').append(iconBase64);
}
Can anybody help me?
I'll have to go against the majority and tell that you can actually get it without a canvas.
The statement that FileReader can't read external files is not completely true :
You can give it a blob as source.
So you can convert your external resource to a Blob object, using XMLHttpRequest
making it available from the local machine so the above statement isn't completely false either,
then get its dataURL from the FileReader.
var file = "http://mw2.google.com/mw-panoramio/photos/medium/23830229.jpg";
var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
getDataURL(this.response);
};
xhr.open('GET', file, true);
// the magic part
xhr.responseType = 'blob';
xhr.send();
function getDataURL(blob) {
var reader = new FileReader();
reader.onload = function(event) {
var dataURL = this.result;
document.querySelector('img').src = dataURL;
document.querySelector('p').innerHTML = dataURL;
};
var source = reader.readAsDataURL(blob);
}
<img/>
<p></p>
You can't use FileReader to solve this problem, because you are not trying to read local files (that is the purpose of FileReader)
Just convert the image taken from the web link using something like this answer https://stackoverflow.com/a/20285053/912450

PNG or JPG (not rgb) over websocket with ArrayBuffer without base64

Is there a way to render a PNG image to canvas without having to encode it to base64?
Server sends a PNG in binary, client receives it in an ArrayBuffer
and displays it on the canvas. Only way I could get this to work is by encoding the data to base64 - on the server side - as I need it to be fast. On the client side, I created an image obj with data:image/png;base64 tag.
I know you can create a blob and a file reader but I could not get that to work.
This is the blob version:
var blob = new Blob([image.buffer],{type: "image/png"});
var imgReader = new FileReader();
imgReader.onload = function (e) {
var img = new Image();
img.onload = function (e) {
console.log("PNG Loaded");
ctx.drawImage(img, left, top);
window.URL.revokeObjectURL(img.src);
img = null;
};
img.onerror = img.onabort = function () {
img = null;
};
img.src = e.target.result;
imgReader = null;
}
imgReader.readAsDataURL(blob);
image is Uint8Array. I create a blob from it. The rest is self-explanatory.
Images are correct and valid PNG images. When I send it from the server, I wrote them to a file on the server side and they render fine with an image viewer.
You can create a blob url with createObjectURL without having to do any base64 encoding, just pass the blob you crated to it and you will have a url you can set as img.src
var blob = new Blob([image],{type: "image/png"});
var img = new Image();
img.onload = function (e) {
console.log("PNG Loaded");
ctx.drawImage(img, left, top);
window.URL.revokeObjectURL(img.src);
img = null;
};
img.onerror = img.onabort = function () {
img = null;
};
img.src = window.URL.createObjectURL(blob);
I've only seen it used in this way. If you don't want to send the base64 via the network, then, you can use the btoa to convert the binary data to a base64 on the client side.
Looking at MDN, drawImage takes a CanvasImageSource object. CanvasImageSource represents any object of type HTMLImageElement, ImageBitmap and few others.
On further searching, I found some information related to ImageBitmap, but, not enough to provide a solution.
I could have added this to the comment, but, it would have become a massive comment and lose all the clarity.

Categories

Resources