Cross Origin Error when using getImageData [duplicate] - javascript

My code is working very well on my localhost but it is not working on the site.
I got this error from the console, for this line .getImageData(x,y,1,1).data:
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
part of my code:
jQuery.Event.prototype.rgb=function(){
var x = this.offsetX || (this.pageX - $(this.target).offset().left),y = this.offsetY || (this.pageY - $(this.target).offset().top);
if (this.target.nodeName!=="CANVAS")return null;
return this.target.getContext('2d').getImageData(x,y,1,1).data;
}
Note: my image url (src) is from a subdomain url

As others have said you are "tainting" the canvas by loading from a cross origins domain.
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
However, you may be able to prevent this by simply setting:
img.crossOrigin = "Anonymous";
This only works if the remote server sets the following header appropriately:
Access-Control-Allow-Origin "*"
The Dropbox file chooser when using the "direct link" option is a great example of this. I use it on oddprints.com to hoover up images from the remote dropbox image url, into my canvas, and then submit the image data back into my server. All in javascript

I found that I had to use .setAttribute('crossOrigin', '') and had to append a timestamp to the URL's query string to avoid a 304 response lacking the Access-Control-Allow-Origin header.
This gives me
var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');

You won't be able to draw images directly from another server into a canvas and then use getImageData. It's a security issue and the canvas will be considered "tainted".
Would it work for you to save a copy of the image to your server using PHP and then just load the new image? For example, you could send the URL to the PHP script and save it to your server, then return the new filename to your javascript like this:
<?php //The name of this file in this example is imgdata.php
$url=$_GET['url'];
// prevent hackers from uploading PHP scripts and pwning your system
if(!#is_array(getimagesize($url))){
echo "path/to/placeholderImage.png";
exit("wrong file type.");
}
$img = file_get_contents($url);
$fn = substr(strrchr($url, "/"), 1);
file_put_contents($fn,$img);
echo $fn;
?>
You'd use the PHP script with some ajax javascript like this:
xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();
xi.onreadystatechange=function() {
if(xi.readyState==4 && xi.status==200) {
img=new Image;
img.onload=function(){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src=xi.responseText;
}
}
If you use getImageData on the canvas after that, it will work fine.
Alternatively, if you don't want to save the whole image, you could pass x & y coordinates to your PHP script and calculate the pixel's rgba value on that side. I think there are good libraries for doing that kind of image processing in PHP.
If you want to use this approach, let me know if you need help implementing it.
edit-1: peeps pointed out that the php script is exposed and allows the internet to potentially use it maliciously. there are a million ways to handle this, one of the simplest being some sort of URL obfuscation... i reckon secure php practices deserves a separate google ;P
edit-2: by popular demand, I've added a check to ensure it is an image and not a php script (from: PHP check if file is an image).

I was seeing this error on Chrome while I was testing my code locally. I switched to Firefox and I am not seeing the error any more. Maybe switching to another browser is a quick fix.
If you are using the solution given in the first answer, then make sure you add img.crossOrigin = "Anonymous"; just after you declare the img variable (for eg. var img = new Image();).

When working on local, add a server.
I had a similar issue when working on local. Your URL is going to be the path to the local file, for example, file:///Users/PeterP/Desktop/folder/index.html.
Please note that I am on a Mac.
I got around this by installing an HTTP server globally. I used https://www.npmjs.com/package/http-server
Steps
Global install: npm install http-server -g
Run server: http-server ~/Desktop/folder/
These steps assume that you have node installed, otherwise you won't get very far running npm commands.

My problem was so messed up I just base64 encoded the image to ensure there couldn't be any CORS issues

Your problem is that you load an external image, meaning from another domain. This causes a security error when you try to access any data of your canvas context.

You are "tainting" the canvas by loading from a cross origins domain. Check out this MDN article:
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image

Set the Image's crossOrigin attribute to Anonymous.
let image = new Image();
// image.src = ...;
image.crossOrigin = `Anonymous`;

As matt burns says in his answer, you may need to enable CORS on the server where the problem images are hosted.
If the server is Apache, this can be done by adding the following snippet (from here) to either your VirtualHost config or an .htaccess file:
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
...if adding it to a VirtualHost, you'll probably need to reload Apache's config too (eg. sudo service apache2 reload if Apache's running on a Linux server)

you can convert the image to a data string as use the image source instead of the actual image source.
[https://www.base64-image.de/][1] to convert image to data string.
Convert and copy string data from the above website.
set image.src = <copied_data_string>.

workaround solution,
convert source image URL to Base64 data and assign to img
for example, use Axios
const getBase64 = async(url)=>{
try {
let image = await axios.get(url, { responseType: 'arraybuffer' });
let raw = Buffer.from(image.data).toString('base64');
return "data:" + image.headers["content-type"] + ";base64,"+raw;
} catch (error) {
console.log(error)
}
}
var image = new Image()
image.src=getBase64(url)
no cross-origin dependency from canvas

I meet the same problem today, and solve it by the code follows.
html code:
<div style='display: none'>
<img id='img' src='img/iak.png' width='600' height='400' />
</div>
<canvas id='iak'>broswer don't support canvas</canvas>
js code:
var canvas = document.getElementById('iak')
var iakImg = document.getElementById('img')
var ctx = canvas.getContext('2d')
var image = new Image()
image.src=iakImg.src
image.onload = function () {
ctx.drawImage(image,0,0)
var data = ctx.getImageData(0,0,600,400)
}
code like above, and there is no cross-domain problem.

I was having the same issue, and for me it worked by simply concatenating https:${image.getAttribute('src')}

Related

JavaScript: Obtain the file-size of an image from the DOM element which loaded it [duplicate]

As part of a web app, once images have been downloaded and rendered on a web page, I need to determine an image's file size (kb) and resolution within the browser context (so I could, for example, display that info on the page. This needs to be done client-side, obviously. Must be able to be solved x-browser without an ActiveX control or Java applet (IE7+, FF3+, Safari 3+, IE6 nice to have), though it doesn't have to be the same solution per browser.
Ideally this would be done using system Javascript, but if I absolutely need a JQuery or similar library (or a tiny subset of it), that could be done.
Edit:
To get the current in-browser pixel size of a DOM element (in your case IMG elements) excluding the border and margin, you can use the clientWidth and clientHeight properties.
var img = document.getElementById('imageId');
var width = img.clientWidth;
var height = img.clientHeight;
Now to get the file size, now I can only think about the fileSize property that Internet Explorer exposes for document and IMG elements...
Edit 2: Something comes to my mind...
To get the size of a file hosted on the server, you could simply make an HEAD HTTP Request using Ajax. This kind of request is used to obtain metainformation about the url implied by the request without transferring any content of it in the response.
At the end of the HTTP Request, we have access to the response HTTP Headers, including the Content-Length which represents the size of the file in bytes.
A basic example using raw XHR:
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'img/test.jpg', true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status == 200 ) {
alert('Size in bytes: ' + xhr.getResponseHeader('Content-Length'));
} else {
alert('ERROR');
}
}
};
xhr.send(null);
Note: Keep in mind that when you do Ajax requests, you are restricted by the Same origin policy, which allows you to make requests only within the same domain.
Check a working proof of concept here.
Edit 3:
1.) About the Content-Length, I think that a size mismatch could happen for example if the server response is gzipped, you can do some tests to see if this happens on your server.
2.) For get the original dimensions of a image, you could create an IMG element programmatically, for example:
var img = document.createElement('img');
img.onload = function () { alert(img.width + ' x ' + img.height); };
img.src='http://sstatic.net/so/img/logo.png';
Check the uploaded image size using Javascript
<script type="text/javascript">
function check(){
var imgpath=document.getElementById('imgfile');
if (!imgpath.value==""){
var img=imgpath.files[0].size;
var imgsize=img/1024;
alert(imgsize);
}
}
</script>
Html code
<form method="post" enctype="multipart/form-data" onsubmit="return check();">
<input type="file" name="imgfile" id="imgfile"><br><input type="submit">
</form>
Getting the Original Dimensions of the Image
If you need to get the original image dimensions (not in the browser context), clientWidth and clientHeight properties do not work since they return incorrect values if the image is stretched/shrunk via css.
To get original image dimensions, use naturalHeight and naturalWidth properties.
var img = document.getElementById('imageId');
var width = img.naturalWidth;
var height = img.naturalHeight;
p.s. This does not answer the original question as the accepted answer does the job. This, instead, serves like addition to it.
How about this:
var imageUrl = 'https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg';
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open('GET', imageUrl, true);
xhr.responseType = 'blob';
xhr.onload = function()
{
blob = xhr.response;
console.log(blob, blob.size);
}
xhr.send();
http://qnimate.com/javascript-create-file-object-from-url/
due to Same Origin Policy, only work under same origin
Regarding the width and height:
var img = document.getElementById('imageId');
var width = img.clientWidth;
var height = img.clientHeight;
Regarding the filesize you can use performance
var size = performance.getEntriesByName(url)[0];
console.log(size.transferSize); // or decodedBodySize might differ if compression is used on server side
Service workers have access to header informations, including the Content-Length header.
Service workers are a bit complicated to understand, so I've built a small library called sw-get-headers.
Than you need to:
subscribe to the library's response event
identify the image's url among all the network requests
here you go, you can read the Content-Length header!
Note that your website needs to be on HTTPS to use Service Workers, the browser needs to be compatible with Service Workers and the images must be on the same origin as your page.
Most folks have answered how a downloaded image's dimensions can be known so I'll just try to answer other part of the question - knowing downloaded image's file-size.
You can do this using resource timing api. Very specifically transferSize, encodedBodySize and decodedBodySize properties can be used for the purpose.
Check out my answer here for code snippet and more information if you seek : JavaScript - Get size in bytes from HTML img src
You can use generic Image object to load source dynamically then measure it:
const img = new Image();
img.src = this.getUrlSource()
img.onload = ({target}) =>{
let width = target.width;
let height = target.height;
}
You can get the dimensions using getElement(...).width and ...height.
Since JavaScript can't access anything on the local disk for security reasons, you can't examine local files. This is also true for files in the browser's cache.
You really need a server which can process AJAX requests. On that server, install a service that downloads the image and saves the data stream in a dummy output which just counts the bytes. Note that you can't always rely on the Content-length header field since the image data might be encoded. Otherwise, it would be enough to send a HTTP HEAD request.
You can find dimension of an image on the page using something like
document.getElementById('someImage').width
file size, however, you will have to use something server-side
var img = new Image();
img.src = sYourFilePath;
var iSize = img.fileSize;
The only thing you can do is to upload the image to a server and check the image size and dimension using some server side language like C#.
Edit:
Your need can't be done using javascript only.

How to fix getImageData() error The canvas has been tainted by cross-origin data?

My code is working very well on my localhost but it is not working on the site.
I got this error from the console, for this line .getImageData(x,y,1,1).data:
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
part of my code:
jQuery.Event.prototype.rgb=function(){
var x = this.offsetX || (this.pageX - $(this.target).offset().left),y = this.offsetY || (this.pageY - $(this.target).offset().top);
if (this.target.nodeName!=="CANVAS")return null;
return this.target.getContext('2d').getImageData(x,y,1,1).data;
}
Note: my image url (src) is from a subdomain url
As others have said you are "tainting" the canvas by loading from a cross origins domain.
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
However, you may be able to prevent this by simply setting:
img.crossOrigin = "Anonymous";
This only works if the remote server sets the following header appropriately:
Access-Control-Allow-Origin "*"
The Dropbox file chooser when using the "direct link" option is a great example of this. I use it on oddprints.com to hoover up images from the remote dropbox image url, into my canvas, and then submit the image data back into my server. All in javascript
I found that I had to use .setAttribute('crossOrigin', '') and had to append a timestamp to the URL's query string to avoid a 304 response lacking the Access-Control-Allow-Origin header.
This gives me
var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
You won't be able to draw images directly from another server into a canvas and then use getImageData. It's a security issue and the canvas will be considered "tainted".
Would it work for you to save a copy of the image to your server using PHP and then just load the new image? For example, you could send the URL to the PHP script and save it to your server, then return the new filename to your javascript like this:
<?php //The name of this file in this example is imgdata.php
$url=$_GET['url'];
// prevent hackers from uploading PHP scripts and pwning your system
if(!#is_array(getimagesize($url))){
echo "path/to/placeholderImage.png";
exit("wrong file type.");
}
$img = file_get_contents($url);
$fn = substr(strrchr($url, "/"), 1);
file_put_contents($fn,$img);
echo $fn;
?>
You'd use the PHP script with some ajax javascript like this:
xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();
xi.onreadystatechange=function() {
if(xi.readyState==4 && xi.status==200) {
img=new Image;
img.onload=function(){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src=xi.responseText;
}
}
If you use getImageData on the canvas after that, it will work fine.
Alternatively, if you don't want to save the whole image, you could pass x & y coordinates to your PHP script and calculate the pixel's rgba value on that side. I think there are good libraries for doing that kind of image processing in PHP.
If you want to use this approach, let me know if you need help implementing it.
edit-1: peeps pointed out that the php script is exposed and allows the internet to potentially use it maliciously. there are a million ways to handle this, one of the simplest being some sort of URL obfuscation... i reckon secure php practices deserves a separate google ;P
edit-2: by popular demand, I've added a check to ensure it is an image and not a php script (from: PHP check if file is an image).
I was seeing this error on Chrome while I was testing my code locally. I switched to Firefox and I am not seeing the error any more. Maybe switching to another browser is a quick fix.
If you are using the solution given in the first answer, then make sure you add img.crossOrigin = "Anonymous"; just after you declare the img variable (for eg. var img = new Image();).
When working on local, add a server.
I had a similar issue when working on local. Your URL is going to be the path to the local file, for example, file:///Users/PeterP/Desktop/folder/index.html.
Please note that I am on a Mac.
I got around this by installing an HTTP server globally. I used https://www.npmjs.com/package/http-server
Steps
Global install: npm install http-server -g
Run server: http-server ~/Desktop/folder/
These steps assume that you have node installed, otherwise you won't get very far running npm commands.
My problem was so messed up I just base64 encoded the image to ensure there couldn't be any CORS issues
Your problem is that you load an external image, meaning from another domain. This causes a security error when you try to access any data of your canvas context.
You are "tainting" the canvas by loading from a cross origins domain. Check out this MDN article:
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
Set the Image's crossOrigin attribute to Anonymous.
let image = new Image();
// image.src = ...;
image.crossOrigin = `Anonymous`;
As matt burns says in his answer, you may need to enable CORS on the server where the problem images are hosted.
If the server is Apache, this can be done by adding the following snippet (from here) to either your VirtualHost config or an .htaccess file:
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
...if adding it to a VirtualHost, you'll probably need to reload Apache's config too (eg. sudo service apache2 reload if Apache's running on a Linux server)
you can convert the image to a data string as use the image source instead of the actual image source.
[https://www.base64-image.de/][1] to convert image to data string.
Convert and copy string data from the above website.
set image.src = <copied_data_string>.
workaround solution,
convert source image URL to Base64 data and assign to img
for example, use Axios
const getBase64 = async(url)=>{
try {
let image = await axios.get(url, { responseType: 'arraybuffer' });
let raw = Buffer.from(image.data).toString('base64');
return "data:" + image.headers["content-type"] + ";base64,"+raw;
} catch (error) {
console.log(error)
}
}
var image = new Image()
image.src=getBase64(url)
no cross-origin dependency from canvas
I meet the same problem today, and solve it by the code follows.
html code:
<div style='display: none'>
<img id='img' src='img/iak.png' width='600' height='400' />
</div>
<canvas id='iak'>broswer don't support canvas</canvas>
js code:
var canvas = document.getElementById('iak')
var iakImg = document.getElementById('img')
var ctx = canvas.getContext('2d')
var image = new Image()
image.src=iakImg.src
image.onload = function () {
ctx.drawImage(image,0,0)
var data = ctx.getImageData(0,0,600,400)
}
code like above, and there is no cross-domain problem.
I was having the same issue, and for me it worked by simply concatenating https:${image.getAttribute('src')}

CORS is enabled but toDataURL still throws a warning

As the title says, I've enabled CORS for all of the images, but I'm still getting errors when trying to throw them onto a canvas and then extract that canvas (Chrome and FF). I ran a little sniffer on one of the images to test it out, and it seems to be in fact returning the correct headers:
Access-Control-Allow-Origin: *
Am I missing something?
You need to request CORS usage for the server, just add this attribute to the image tag:
<img crossOrigin="anonymous" ... />
or dynamically from JavaScript, use it as property (assuming img is created or obtained already):
var img = new Image;
img.onload = callback;
img.crossOrigin = ''; /// = anonymous
img.src = '...';
If you have multiple images to load you can use an image loader that supports cross-origin request (for example my YAIL loader where you can request all or individual images to be loaded using CORS).

Reading image capture files in PhoneGap

I'm working on a PhoneGap application that captures images using the camera and, later, uploads them. There are two modes of operation for camera in PhoneGap: raw base64 encoded data or a file URI.
The docs themselves say:
Note: The image quality of pictures taken using the camera on newer
devices is quite good. Encoding such images using Base64 has caused
memory issues on some of these devices (iPhone 4, BlackBerry Torch
9800). Therefore, using FILE_URI as the 'Camera.destinationType' is
highly recommended.
So I'm keen to use FILE_URI option. This works great and you can even show the images in IMG tags. The URL looks like this:
file://localhost/var/mobile/Applications/4FE4642B-944C-449BB-9BD6-1E442E47C7CE/tmp/photo_047.jpg
However, at some point later I want to read the contents of the file to upload to a server. I was going to do this using the FileReader type. This doesn't work and I think it's because I can't access the file at the URL above.
The error code I get back from readDataUrl is 1 > FileError.NOT_FOUND_ERR = 1;
Any ideas how I can get to the file? I tried just accessing the last part of the path (photo_047.jpg) based on another sample I saw but no luck.
I'm just getting started with PhoneGap, and given the age of this question you may have found an answer already, but I'll give it a try anyway.
First, would you be able to use the built-in FileTransfer object? It takes a file: URI as an argument.
If FileTransfer won't work for you, and you need to read the file data yourself, you'll need the PhoneGap File objects, like FileReader , as you said. But most of those expect a plain pathname -- not a URI -- to specify the file to work with. The reason you're getting NOT_FOUND_ERR is because it's trying to open a file named file:/localhost/var....
Here's a quick one-liner to extract the path part from your URI:
var path = /file:\/\/.*?(\/.*)/.exec(fileuri)[1];
Hope this helps!
The answer from jgarbers was of help to me but it did not solve the problem. I realized the camera stores photos in Temp folder instead of Document folder. Setting my local file system to temporary allowed it to find the correct location for the camera images.
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
var path = /file://.?(/.)/.exec(fileuri)[1];
Ref. above jgarbers and Rik answers (solution has been tested successfully on iOs 7)
you can user the file transfer plugin for uploading any file to the server.
//// pass your file uri to the mediafie param
function uploadFile(mediaFile) {
var ft = new FileTransfer();
path = mediaFile.fullPath;
name = mediaFile.name;
////your service method url
var objUrl = http://example.com;
ft.upload(path,
objUrl,
function (result) {
alert("Success");
},
function (error) {
alert('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}

Determining image file size + dimensions via Javascript?

As part of a web app, once images have been downloaded and rendered on a web page, I need to determine an image's file size (kb) and resolution within the browser context (so I could, for example, display that info on the page. This needs to be done client-side, obviously. Must be able to be solved x-browser without an ActiveX control or Java applet (IE7+, FF3+, Safari 3+, IE6 nice to have), though it doesn't have to be the same solution per browser.
Ideally this would be done using system Javascript, but if I absolutely need a JQuery or similar library (or a tiny subset of it), that could be done.
Edit:
To get the current in-browser pixel size of a DOM element (in your case IMG elements) excluding the border and margin, you can use the clientWidth and clientHeight properties.
var img = document.getElementById('imageId');
var width = img.clientWidth;
var height = img.clientHeight;
Now to get the file size, now I can only think about the fileSize property that Internet Explorer exposes for document and IMG elements...
Edit 2: Something comes to my mind...
To get the size of a file hosted on the server, you could simply make an HEAD HTTP Request using Ajax. This kind of request is used to obtain metainformation about the url implied by the request without transferring any content of it in the response.
At the end of the HTTP Request, we have access to the response HTTP Headers, including the Content-Length which represents the size of the file in bytes.
A basic example using raw XHR:
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'img/test.jpg', true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status == 200 ) {
alert('Size in bytes: ' + xhr.getResponseHeader('Content-Length'));
} else {
alert('ERROR');
}
}
};
xhr.send(null);
Note: Keep in mind that when you do Ajax requests, you are restricted by the Same origin policy, which allows you to make requests only within the same domain.
Check a working proof of concept here.
Edit 3:
1.) About the Content-Length, I think that a size mismatch could happen for example if the server response is gzipped, you can do some tests to see if this happens on your server.
2.) For get the original dimensions of a image, you could create an IMG element programmatically, for example:
var img = document.createElement('img');
img.onload = function () { alert(img.width + ' x ' + img.height); };
img.src='http://sstatic.net/so/img/logo.png';
Check the uploaded image size using Javascript
<script type="text/javascript">
function check(){
var imgpath=document.getElementById('imgfile');
if (!imgpath.value==""){
var img=imgpath.files[0].size;
var imgsize=img/1024;
alert(imgsize);
}
}
</script>
Html code
<form method="post" enctype="multipart/form-data" onsubmit="return check();">
<input type="file" name="imgfile" id="imgfile"><br><input type="submit">
</form>
Getting the Original Dimensions of the Image
If you need to get the original image dimensions (not in the browser context), clientWidth and clientHeight properties do not work since they return incorrect values if the image is stretched/shrunk via css.
To get original image dimensions, use naturalHeight and naturalWidth properties.
var img = document.getElementById('imageId');
var width = img.naturalWidth;
var height = img.naturalHeight;
p.s. This does not answer the original question as the accepted answer does the job. This, instead, serves like addition to it.
How about this:
var imageUrl = 'https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg';
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open('GET', imageUrl, true);
xhr.responseType = 'blob';
xhr.onload = function()
{
blob = xhr.response;
console.log(blob, blob.size);
}
xhr.send();
http://qnimate.com/javascript-create-file-object-from-url/
due to Same Origin Policy, only work under same origin
Regarding the width and height:
var img = document.getElementById('imageId');
var width = img.clientWidth;
var height = img.clientHeight;
Regarding the filesize you can use performance
var size = performance.getEntriesByName(url)[0];
console.log(size.transferSize); // or decodedBodySize might differ if compression is used on server side
Service workers have access to header informations, including the Content-Length header.
Service workers are a bit complicated to understand, so I've built a small library called sw-get-headers.
Than you need to:
subscribe to the library's response event
identify the image's url among all the network requests
here you go, you can read the Content-Length header!
Note that your website needs to be on HTTPS to use Service Workers, the browser needs to be compatible with Service Workers and the images must be on the same origin as your page.
Most folks have answered how a downloaded image's dimensions can be known so I'll just try to answer other part of the question - knowing downloaded image's file-size.
You can do this using resource timing api. Very specifically transferSize, encodedBodySize and decodedBodySize properties can be used for the purpose.
Check out my answer here for code snippet and more information if you seek : JavaScript - Get size in bytes from HTML img src
You can use generic Image object to load source dynamically then measure it:
const img = new Image();
img.src = this.getUrlSource()
img.onload = ({target}) =>{
let width = target.width;
let height = target.height;
}
You can get the dimensions using getElement(...).width and ...height.
Since JavaScript can't access anything on the local disk for security reasons, you can't examine local files. This is also true for files in the browser's cache.
You really need a server which can process AJAX requests. On that server, install a service that downloads the image and saves the data stream in a dummy output which just counts the bytes. Note that you can't always rely on the Content-length header field since the image data might be encoded. Otherwise, it would be enough to send a HTTP HEAD request.
You can find dimension of an image on the page using something like
document.getElementById('someImage').width
file size, however, you will have to use something server-side
var img = new Image();
img.src = sYourFilePath;
var iSize = img.fileSize;
The only thing you can do is to upload the image to a server and check the image size and dimension using some server side language like C#.
Edit:
Your need can't be done using javascript only.

Categories