Load image into canvas using a generic handler - javascript

is it possible to load an image directly into a canvas control using a generic handler without using the image element?
This is my handler:
public void ProcessRequest(HttpContext context)
{
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
context.Response.ContentType = "image/jpeg";
var camIndex = Convert.ToInt16(context.Request.QueryString["camIndex"]);
context.Response.BinaryWrite( Shared.Feeder[camIndex].JpegData);
}
My JavaScript:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1/Media/FrameHandler.ashx?camIndex=' + camIndex, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
var uInt8Array = new Uint8ClampedArray(this.response);
imageData[camIndex].data.set(uInt8Array);
ctxLiveViews[camIndex].putImageData(imageData[camIndex], 0, 0);
};
xhr.send();
which gives me this image (which is obviously wrong)

Is it possible to load an image directly into a canvas control using a generic handler without using the image element?
It is, but you are in for a hand-full as you will need to manually parse the image file format yourselves (with all the various combinations of image format, color model etc. and error checks and so forth). It's doable (been there done that), but chances are, unless you need to access some special data or bitmap formats, that the browser will do the job at least faster than a manual approach in JavaScript.
Using an Image element is easy and does all these steps for you in compiled code.
This line:
var uInt8Array = new Uint8ClampedArray(this.response);
will only hold the original file bytes, uncompressed, undecoded including header, chunks and metadata. While putImageData() require a raw bitmap in the format RGBA per pixel. This is why you see the noise as the data being fed to putImageData is the file itself, not a bitmap.

Related

JS: how can I base64 encode a local file without XMLHttpRequest?

I'm trying to base64 encode a local file. It's next to my .js file so there's no uploading going on. Solutions like this (using XMLHttpRequest) get a cross-site scripting error.
I'm trying something like this (which doesn't work but it might help explain my problem):
var file = 'file.jpg'
var reader = new FileReader();
reader.onload = function(e) {
var res = e.target.result;
console.log(res);
};
var f = reader.readAsDataURL(file);
Anyone have any experience doing this locally?
Solutions like this (using XMLHttpRequest) get a cross-site
scripting error.
If using chrome or chromium browser, you could launch with --allow-file-access-from-files flag set to allow request of resource from local filesystem using XMLHttpRequest() or canvas.toDataURL().
You can use <img> element, <canvas> element .toDataURL() to create data URL of local image file without using XMLHttpRequest()
var file = "file.jpg";
var img = new Image;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
img.onload = function() {
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
var res = canvas.toDataURL("image/jpeg", 1); // set image `type` to `image/jpeg`
console.log(res);
}
img.src = file;
You could alternatively use XMLHttpRequest() as described at Convert local image to base64 string in Javascript.
See also How to print all the txt files inside a folder using java script .
For a details of difference of returned data URI from either approach see canvas2d toDataURL() different output on different browser
As described by #Kaiido at comment below
it will first decode it, at this stage it's still your file, then it
will paint it to the canvas (now it's just raw pixels) and finally it
will reencode it (it has nothing to do with your original file
anymore) check the dataURI strings... They're compeltely different and
even if you do the canvas operation from two different browsers,
you'll have different outputs, while FileReader will always give you
the same output, since it encode the file directly, it doesn't decode
it.

display multi page tiff in browser

I'd like to know if there is any way so that I can display a multi-paged tif image in browser using client-side coding (not server-side) in a way that user can navigate between the pages like common jquery photo libraries. I found Tiff.js from https://github.com/seikichi/tiff.js, but this library only gives download link of multi-paged tiff and do not display it in html.
I can do it in server-side using libraries like ImageMagic, LibTiff.Net etc but don't want to because the number of photos are huge and if I do that it consume the large amount of server's cpu
do you know any alternative solution??
I had this problem too and converting the images was not an option for us.
You can use tiff.js that you linked to, have a look at the demo and then view source at http://seikichi.github.io/tiff.js/multipage.html.
$(function () {
Tiff.initialize({TOTAL_MEMORY: 16777216 * 10});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'images/multipage.tiff');
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
var buffer = xhr.response;
var tiff = new Tiff({buffer: buffer});
for (var i = 0, len = tiff.countDirectory(); i < len; ++i) {
tiff.setDirectory(i);
var canvas = tiff.toCanvas();
$('body').append(canvas);
}
};
xhr.send();
});
Replace 'images/multipage.tiff' with the path to your file and it will add each page to the body element (just replace $('body') with your element if you want it somewhere else). Works with single tiff as well.
Browsers won't support tif images.
check this Wiki Link.
You have to generate a png image and store it and show that in browser for the tif.

How do you get the file size of an image on the web page with Javascript?

I'd like to be able to get the file size on an image on a webpage.
So let's say I have an image on the page (that has loaded) like this:
How do I call a function in Javascript (or, even better, jquery) to get the file size (not the dimensions) of the image?
It's important to note that I'm not using any inputs or having users upload the image, there's lots of SO answers on getting image sizes from browse buttons with the file API.
All I want to do is get the file size of any arbitrary image on the page based of it's id and src url.
Edit: I'm dealing with a keep-alive connection for some images so the Content-Length headers are not available.
You can't directly get the file size (or any data from it).
The only way is a bit dirty, because you have to do a XMLHTTPRequest (and it probably won't work with externals images, according to the "Cross Origin Resource Sharing"). But with the browser's cache, it should not cause another HTTP request.
var xhr = new XMLHttpRequest();
xhr.open("GET", "foo.png", true);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function() {
if(this.readyState == this.DONE) {
alert("Image size = " + this.response.byteLength + " bytes.");
}
};
xhr.send(null);
Here is a React version that worked for me, posting it in the event that it could save some time.
Form field
<input type="file"
name="file"
id="file"
multiple="multiple"
onChange={onChangeHandler}
className="fileUp" />
JSX
const onChangeHandler = event => {
console.log(event.target.files[0].size);
}
Old question but here is my take: I had the same issue but didn't want te rely on buffering to prevent my app from downloading the images twice (as the accepted answer does). What I ended up doing was fetch the file as a blob, read the file size, and use the blob as image source from there on. this was easily done with the URL.createObjectURL() function like so:
let img = new Image()
img.crossOrigin = "Anonymous"; // Helps with some cross-origin issues
fetch('foo.png')
.then(response => response.blob())
.then(blob => { img.src = URL.createObjectURL(blob); })
This looks a lot cleaner and perhaps it can still be useful for some.
Assuming you could use HTML5
Create a canvas
Put image in there
Grab the image data with .toDataURLHD()
Grab the base64 encoded string
Use some mad calculation to get the image size in bytes.
Have fun!
Maybe it's a lot easier to use a server side script, so it won't be HTML5-dependant

Reading binary data into JavaScript

I've got a WebGL application which requires me to load a lot of x,y vertex data, but to minimise bandwidth usage I want to also compress the data (on a one off basis) using gzip.
Below is the code I will use to load in the data. I want to retrieve data from a server and pass it straight into a Float32Array.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'array.gz', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(data) {
console.log("loaded");
var dataArray = new Float32Array(this.response);
xhr.onprogress = function(e) {
};
xhr.onerror = function(error) {
console.log('error!');
};
xhr.send();
Now my problem isn't linked to the code directly, but to the file format supported. In what format (i.e. csv, json, xml) does the data need to be in, before being gzipped so that this method can properly consume it?
I've played around to find that if I JSON.stringify a Float32Array and place the content in a file, then load it in, it works fine. However, to load in all my uncompressed data into a JavaScript array, before copying all its contents back into a new file to be compressed isn't very feasible. So I'm really looking for an alternative way to this (assuming this file format is the only one supported).

How to get image content (not url) from IMG element?

We are using the Eclipse SWT WebBrowser control to render HTML pages for our Java application. If the page contains an image, we want to get the image content. We can access the DOM to get the IMG element, but there doesn't seem to be a way to get the actual content (i.e. the bytes of the image) other than re-fetching the image using the image URL. (We can get the image URL via the 'src' attribute.) Is there any way to get the actual bytes of the image from the DOM?
I am not sure if this is what you are looking for, but basically you can just make a typed XHR (such as ArrayBuffer) to the image source (it should be cached, so no real hit by doing this). I am assume you are using an HTML5 compliant browser (or such that supports ArrayBuffer or the type you need). I am assuming the document has at least one image with a proper source, see Fiddle for working demo.
var img = document.querySelector('img'), xhr = new XMLHttpRequest();
xhr.open('GET', img.src, true);
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', handleBuffer, false);
xhr.send();
// Your image data ArrayBuffer, feel free to change the type.
function handleBuffer (data) {
var arryBuffer = data.target.response;
}
Sample Fiddle
Check out https://developer.mozilla.org/en-US/docs/Web/API/FileReader it will let you create base64 data urls, may not work depending on your browser versions.

Categories