HTML5 Canvas won't render data received from canvas.toDataURI() - javascript

I've got an HTML5 Canvas. I .toDataURI it and send that off to PHP with AJAX. PHP stores that in a database.
Then I have a different page that has an img element to request that data from the database and render it. But it... won't. The data's getting through, I can see it with the browser's view source function:
<img id="embedded" src="data:image/png;base64,iVBORw...5CYII=" />
(ellipsis added)
It's not being truncated or anything stupid like that, I have document.write's and echo's in every script from where the data is generated by the canvas to where it's embedded into the final element, and it's getting through completely intact.
I've tried it with image URIs generated by other sources and there's no problem. I've tested this in Chrome 12 and Firefox 5, behavior was identical in both.
A final oddity is that when the canvas is totally blank, the image data it generates IS displayed: I get a blank image with the same dimensions as the original canvas. But as soon as I draw anything on it, nothing. Just the familiar little error-loading-image icon.
This is my code for the receiving end:
http://pastebin.com/Hw1ykd1i
And for the sending end:
http://pastebin.com/hwsEfsaD

If I've fully understood your problem - you're saying the receiver isn't working (i.e. the thing that mirrors out the output).
You need to encode your data:
function postToServer(data) {
data = "data=" + encodeURIComponent(data);
// continue with XHR POST
This works with the blank canvas because it's made up of letters without any symbols. As soon as you draw, the canvas base64 value has characters such as + in it, which in POST language means space. So if you encodeURIComponent your value, those symbols will get sent intact to your server, and the receiver thingy should be able to render the output correctly.

Related

Error with downloading image as data url

So, i was doing a link to download an image from a data url(a LARGE one):
<a download='fileName' href="data:image/png;base64,/9j/4WSsRX...">something</a>
However, whenever i try to click in that link i receive an error telling me some net problems.
I have make a fiddle test, but its LARGE(15mb of text) and it will take sometime to load:
https://jsfiddle.net/jjydp1ek/
As the jsfiddle is hard to load, i added a file in mediafire:
http://www.mediafire.com/download/p85y1g442ne9v6m/new++7.html
The test is an image with the same data url value as the link, the image is visible, however i see that the option to open image in a new tab on chrome isn't working.
I do it with canvas in ie 11 and is failing too
Questions:
It is ever possible to make it work with the download link as it is now?
Is there a limit size with the data url to download a file, which is?
How do i do to make the user able to download that image?
Also, ask questions here, or correct any error in the text you see if you think its not understandable.
Thanks.
I have a 70Mb broadband and a powerhouse of a PC and that JS fiddle won't even open.
I don't think it's feasible to have a 15MB encoded string, since that has to be downloaded onto the page each time on every visit. I would try the following:
Optimise the image, you could incorporate gulp-imagemin if you have/want to have Gulp for a build system. I think there are alternatives for Grunt if you wanted to go that way.
Store the file on the server and just place a link to the path, this is the preferred solution.
In response to your questions
The limit:
Length limitations
Although Mozilla supports data URIs of essentially
unlimited length, browsers are not required to support any particular
maximum length of data. For example, the Opera 11 browser limits data
URIs to around 65000 characters.
Source: data URIs - MDN
Downloading
The above suggestion on optimising the image as small as you can get without losing quality if that's a concern. Try it then. If not, it's not a problem to give the user a link to the image / display it on the page. The user can right click and save.
Note
By the time I finished writing this response JSFiddle timed out.

Replace/Purge/Remove Cached Image (NOT Refresh)

I've read every question (I believe) about image caching and they mostly address the refesh issue. What I need to do instead, is to "get rid" once and for all of cached images loaded through a JS script.
Backrgound: as part of a tool available on a public website, I need to load images from random websites and analyze them, without the need for displaying them. In summary it's just a loop with a function like this (which works fine):
var img = new Image();
img.onload = function(){//analysys};
img.src = curImg.url;
The problem is that in the process there might be the occasional inappropriate image, which I can't leave on the user's device and asking the user to empty the browser's cache is truly the very last resort.
Having no control on the server side, I searched for ways to prevent client-side caching and tried the various META tags without success. The last idea I'm left with is to "trick" the browser into replacing a cached image with one that I provide, but I have no idea if this is something that can be done in JS at all (at least without "illegal" hacks).
Is there any way to get rid of the unwanted images?

encoding WAV data in Javascript

I am generating WAV data using JavaScript, and I'm able to generate the data and store it in a variable waveFileOutput, then send it to an embedded player by setting the source to following dataURI I set up:
var dataURI = "data:audio/wav;base64," + escape(btoa(waveFileOutput));
I'm also able to get the file to (sort of) "save" by opening a window using the same data after encoding it and saving the window as a file. The problem is that the data is not properly encoded as a WAV file in the new window, even though the embedded play is fine with the encoding. I need to figure out the correct way to encode it. Here are a couple of things I've tried (but neither works):
Try #1: window.open("data:application/octet-stream," +
encodeURIComponent(waveFileOutput));
Try #2: window.open("data:application/octet-stream," +
escape(btoa(waveFileOutput)));
I can post the whole (working) file if that helps, but seemed like it might be a waste of space.
Suggestions for how to get the data encoded properly when "saving" it using this approach?

Force image caching with javascript

I am trying to clone an image which is generated randomly.
Although I am using the exact same url a different image is load. (tested in chrome and firefox)
I can't change the image server so I am looking for a pure javascript/jQuery solution.
How do you force the browser to reuse the first image?
Firefox:
Chrome:
Try it yourself (maybe you have to reload it several times to see it)
Code:
http://jsfiddle.net/TRUbK/
$("<img/>").attr('src', img_src)
$("<div/>").css('background', background)
$("#source").clone()
Demo:
http://jsfiddle.net/TRUbK/embedded/result/
You can't change the image server if it isn't yours, but you can trivially write something on your own server to handle it for you.
First write something in your server-side language of choice (PHP, ASP.NET, whatever) that:
Hits http://a.random-image.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes and downloads it. You generate a key in one of two way. Either get a hash of the whole thing (MD5 should be fine, it's not a security-related use so worries that it's too weak these days don't apply). Or get the size of the image - the latter could have a few duplicates, but is faster to produce.
If the image isn't already stored, save it in a location using that key as part of its filename, and the content-type as another part (in case there's a mixture of JPEGs and PNGs)
Respond with an XML or JSON response with the URI for the next stage.
In your client side-code, you hit that URI through XmlHttpRequest to obtain the URI to use with your images. If you want a new random one, hit that first URI again, if you want the same image for two or more places, use the same result.
That URI hits something like http://yourserver/storedRandImage?id=XXX where XXX is the key (hash or size as decided above). The handler for that looks up the stored copies of the images, and sends the file down the response stream, with the correct content-type.
This is all really easy technically, but the possible issue is a legal one, since you're storing copies of the images on another server, you may no longer be within the terms of your agreement with the service sending the random images.
You can try saving the base64 representation of the image.
Load the image in an hidden div/canvas, then convert it in base64. (I'm not sure if a canvas can be hidden, nor if it is possible to convery the img using html4 tag)
Now you can store the "stringified" image in a cookie, and use it unlimited times...
The headers being sent from your random image generator script include a Cache-Control: max-age=0 declaration which is in essence telling the browser not to cache the image.
You need to modify your image generator script/server to send proper caching headers if you want the result to be cached.
You also need to make sure that the URL stays the same (I didn't look at that aspect since there were tons of parameter being passed).
There seems to be two workarounds:
If you go with the Canvas method, see if you can get the image to load onto the Canvas itself so that you can manipulate the image data directly instead of making a 2nd http request for the image. You can feed the image data directly onto a 2nd Canvas.
If you're going to build a proxy, you can have the proxy remove the No-Cache directive so that subsequent requests by your browser use the cache (no guarantees here - depends on browser/user settings).
First off, you can "force" anything on the web. If you need to force things, then web development is the wrong medium for you.
What you could try, is to use a canvas element to copy the image. See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images for examples.
Tell it to stop getting a random image, seems to work the way you want when I add this third replace call:
// Get the canvas element.
var background = ($("#test").css('background-image')),
img_src = background.replace(/^.+\('?"?/, '').replace(/'?"?\).*$/, '').replace(/&fromrandomrandomizer=yes/,'')
try:
var myImg = new Image();
myImg.src = img_src;
and then append "myImg" to where you want:
$(document).append(myImg);
I did this with your fiddler scripts and got the same image every time
#test {
background:url(http://a.random-image.net.nyud.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes);
width: 150px;
height: 150px;
}
note the .nyud.net after the domain name.

Display dynamically created php image after POSTing data

I have a php script which outputs an image, how can I POST data to it and display the resulting image without refreshing the rest of the screen, so far I have got the code below which returns a png.
function go(){
$.post("test_image.php", $("frm").serialize(),
function(data){
//alert(data);//proves a png image is returned.
//How do I now display the returned image (preferably to '$("#modified")')
});
}
I can't display the returned image.
You could take the resulting data and put it into a data: URI (more info here) but that won't work in IE, is likely to be slow, is not cachable in any way and uses 33% more memory than necessary due to the base64 encoding.
The most elegant way would be for your script to write the image data to a file, and to return the URL of that new image.
Your Ajax callback could then do a simple
$("#myimage").src = data;

Categories