html5 Image Filters with Canvas - javascript

I have download the source from this http://www.storminthecastle.com/projects/imagefilters1/. It is regarding some image manipulation in html5 canvas.
Inside the source, it will load the image located in a local directory...
function reset() {
imageURL = "./sandbox.jpg";
imageFilter = grayscale;
document.querySelector("#filename").innerHTML = "";
update();
}
The above is working in my project. But I am trying to load an image from an url, so I modified it to the following...
function reset() {
imageURL = "http://xxxxxx.jpg";
imageFilter = grayscale;
document.querySelector("#filename").innerHTML = "";
update();
}
When I test it, the image is being displayed correctly. However, all the features are not working anymore and I don't know why. I have no idea why it cannot take in url as the argument and I don't know how to modify it to make it work. Any helps?

Thanks for the link provided. I further read on the COR issue and managed to locate that line of coding to be added.
img.crossOrigin = '';
//img domain different from app domain
img.src = 'http://xxx.jpg';
Simply set the crossOrigin property of the image to make it work. Basically, this will allow cross domain image for manipulation. Without it, any cross domain will be blocked and you will get the security exception. Really thanks for the helps! :)
To add-on, I have only tested using Chrome and is working.

Related

CORS issue with canvas only when image is preloaded

My issue only arises when the loaded image was preloaded somewhere else. For example, when I somewhere use a <img>-tag with the src attribute.
Have a look at this code:
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;" ></canvas>
<img src="https://local-spaces.fra1.digitaloceanspaces.com/test.jpg" width="50"/>
<button onclick="show()">Load Canvas Picture</button>
<script>
function show() {
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function(){
ctx.drawImage(img,0,0, 300, 150);
};
img.src = "https://local-spaces.fra1.digitaloceanspaces.com/test.jpg"
}
</script>
Note: If you are seeing the image in canvas correctly, please cache+hardreload your browser to see the error.
If you are clicking on the button and open your console, you will see that you are getting a CORS-error:
Access to image at
'https://local-spaces.fra1.digitaloceanspaces.com/test.jpg' from
origin 'null' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
Now let's take the next example to see that it is working without preloading the image: https://jsfiddle.net/akzxp9vs/
Note: To make this example work, it's super important that you are deleting your cache + hard reload your browser.
Only then you see that the correct header response is giving back.
Any ideas what I can do?
The image is on the S3 Cloud of Digital Ocean, called Spaces. The image itself is set to public and the CORS setting are set to:
The browser needs to know to check for CORS permissions when the HTTP request is made (i.e. to include an Origin header etc).
When you create a new Image object, it uses the cached data from the <img> element.
Add a crossorigin attribute to the existing <img> element or remove that <img> element entirely.
I found a better solution to my problem. #Quentin's solution is principally right, but it's just not practicable. I tried to update all <img>-tags, however in my page I have dozens of packages that are using the <img>-tag as well.
For example Leaflet. It's like Google Maps, but with Open Street Maps. You just don't have the control over to set attributes like crossorigin in custom icons.
So there had to be another solution. It feels bad to use it, but it does the job.
const src = new URL(imgUrl);
src.searchParams.append('cors', Date.now());
return src.href;
This code appends to your URL a query parameter and forces Chrome to reload the image without being cached.

Can't save canvas as image on Edge browser

I am using fabric js for my web application. For saving HTML5 canvas as image using fabric js, I found the following code which works in chrome and firefox browser. But when i run th same code in microsoft edge, the browser just opens a blank new window without any image on it.
$(".save").click(function () {
canvas.deactivateAll().renderAll();
window.open(canvas.toDataURL('png'));
});
However I also tested many fiddle projects which shows how to convert canvas to an image. Those fiddles works on chrome but not in edge. An example fiddle is here
If you will use FileSaver.js it will download on Edge. For using FileSaver.js you need to convert base64 data into the blob data. To do that, please check this post on StackOverflow
Here is an updated fiddle
You need to include FileSaver.js into your project, and your save button will have the following code:
$("#canvas2png").click(function(){
canvas.isDrawingMode = false;
if(!window.localStorage){alert("This function is not supported by your browser."); return;}
var blob = new Blob([b64toBlob(canvas.toDataURL('png').replace(/^data:image\/(png|jpg);base64,/, ""),"image/png")], {type: "image/png"});
saveAs(blob, "testfile1.png");
});
Alternative, quick and dirt solution is to write html data into new tab, and right click on the image and save it. This solution is not required any plugins or libraries.
Your save will simply change to:
$("#canvas2png").click(function(){
canvas.isDrawingMode = false;
if(!window.localStorage){alert("This function is not supported by your browser."); return;}
var html="<img src='"+canvas.toDataURL()+"' alt='canvas image'/>";
var newTab=window.open();
newTab.document.write(html);
});
Check the modified fiddle:
http://jsfiddle.net/9hrcp/164/
document.getElementById('test').src = canvas.toDataURL('image/png');
i added an image tag and and set the src attribute to the dataUrl to the image and it loads fine.
So edge is generating a correct png, is refusing to load it as a dataUrl redirect. May be a feature and not a bug.

DOM Exception 18 getImageData

I've run into an error that a lot of people seem to have gotten in the past but the explanations are not clear to me. After using the .getImageData() method in my javascript to get the pixel data of a picture that I have stored on my computer and inputed into an img tag in my HTML webpage I get the SecurityError: DOM Exception 18.
I'm simply running an HTMl file in my browser and it is preventing me from getting this stuff done. I've read about making a proxy to get around it or something or hosting the image on my own domain. I don't exactly understand what this means or how to go about doing it. So, it'd be greatly appreciated if anyone could help. I'll input my code here and leave a link to the image as well.
http://i.imgur.com/8UzWlWX.png
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Test</title>
<script>
function putimg() {
var img = document.getElementById('img');
var can = document.getElementById('C');
var ctx = can.getContext('2d');
ctx.drawImage(img, 0, 0);
var position = [];
var imgdata = ctx.getImageData(0,0, img.width, img.height);
var data = imgdata.data;
for (var i = 0; i < data.length; i += 4) {
if (data[i] == 255) {
var vertical = Math.floor((data.indexOf(data[i]) / 4) / 400);
var horizontal = Math.floor((data.indexOf(data[i]) / 4) % 400);
position.push(horizontal, vertical);
}
}
}
ctx.putImageData(imgdata, 0, 0);
}
</script>
</head>
<body onload="putimg()">
<h1>Test</h1>
<img id="img" src="circle-image-alone.png" style="display:none"></img>
<canvas id="C" width="600" height="600"></canvas>
</body>
</html>
EDIT: the file is now in the same folder as the html file, but the same error flag appears
The problem is that this is breaking Same-origin policy. You need to either have imgur relax their Cross-origin sharing or host the image yourself.
If you are running the HTML file directly from the file system on your computer then you can just download the image to the same folder as your html file is in, and reference it like
<img id="img" src="8UzWlWX.png" style="display:none"></img>
Here are the hoops you need to jump through to make it work through a foreign origin like imgur: https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
As you've discovered, your browser considers even your local file system to be a different domain.
So you’re still violating cross-domain even if your image and .html are in the same local directory.
You need a CORS compliant way of loading your image.
Here’s how:
Open up an account on dropbox.com and host your image there.
Be sure to put your image in the “public” folder they set up for you.
They allow cross-domain downloading of their images from your “public” folder.
To get the URL of your dropbox image:
Right-click the image in your public folder and select “copy public link”.
This will put the url into your clipboard where you can paste it into your code.
Then use this code to download your image into the browser in a CORS compliant way:
// download an image from dropbox.com
// in a CORS compliant way
var img=new Image();
img.onload=function(){
ctx.drawImage(img, 0, 0);
}
img.crossOrigin="anonymous";
img.src="dropbox.com/yourDropboxAccount/yourImage.png";
The result is an image that you can fully examine/change/save with:
ctx.getImageData
ctx.putImageData
ctx.toDataURL.

GIF Image Stops when "document.location.href"

I have this function in javascript :
function loadPage (url){
showLoadPageGif(); // visibility On
document.location.href = getPath + "/" + url ;
}
When I use this function , GIF image is displayed in the screen but not working .
someone has fought before, with this problem ? thnx
i recently ran into this issue using animated SVGs as background-images in pseudo elements. I purposefully put in a large delay on my webserver so i could stay on the current page after window.location = url; It was weird that all other CSS animations and hovers still worked, but the SVG cog just stuck.
After some playing around i found that the animations continued to run if, instead of changing window.location, i submitted a GET form.
var url;
//load & setup loading animation
//then generate and submit form with a slight delay
setTimeout(function(){
var new_form;
new_form = document.createElement('form');
new_form.method = 'GET';
new_form.action = url;
document.body.appendChild(new_form);
new_form.submit();
}, 100)
tested on safari 5.1, firefox 24, chrome 32
I assume you mean "GIF animation stops".
This is the correct behavior. Since you go to a new page, all resources for the old page are freed. This of course includes the GIF itself.
You don't "see" this happening because the browser doesn't waste any time rendering a blank page when you assign location.href.
What you need to do is use an AJAX to request the new page and then replace the whole DOM with the new one in the success handler.
There is a bug in IE6 which stops the animations when you start an AJAX request; to fix that, just assign the src attribute of the image again (i.e. img.src = img.src;) to restart them.
Which browser you're using ? I needed to do the same one time if you're using IE just do this :
var loadingFigure = $('#myImage');
var html = loadingFigure.html();
window.location.href = 'myImage';
loadingFigure.html(html);
For firefox is more complicated you need to use an iframe and do something like this :
<iframe id="myIframe" src="/images/busy.gif" scrolling="no" frameborder="0"></iframe>
$('#myIframe').attr('src', '/images/busy.gif');
window.location.href = 'mylocation'
$('#myIframe').attr('src', '/images/busy.gif');

Download a Html5 canvas element as an image with the file extension with Javascript

I would like to be able to download a Html5 canvas element as an image with the file extension with Javascript.
The CanvasToImage library does not seem to be able to achieve this.
Here is my code so far which you can see at this JsFiddle.
<div id="canvas_container">
</div>
<p>
create
download
</p>
$("#create_image").click(function() {
var cnvs = createSmileyOnCanvas();
$('#canvas_container').append(cnvs);
});
$("#download_image").click(function() {
var img = $('#smiley_canvas').toDataURL("image/png");
var uriContent = "data:application/octet-stream," + encodeURIComponent(img);
window.open(uriContent, 'download smiley image');
});
function createSmileyOnCanvas() {
var canvas = document.createElement('canvas');
canvas.id = 'smiley_canvas';
var ctx = canvas.getContext('2d');
// Draw shapes
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // Mouth
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye
ctx.stroke();
return canvas;
}
This seems to work for me:
<a id="downloadImgLink" onclick="$('#downloadImgLink').attr('href', canvas.toDataURL());" download="MyImage.png" href="#" target="_blank">Download Drawing</a>
In order to force/suggest a file name in the browser's download dialog, you would need to send the Content-Disposition: attachment; filename=foobar.png header.
This is not possible to do via window.open, so you're out of luck unless there are some browser-specific hacks for this.
If you really need the filename, you could try using the new download attribute in a, <a href="put stuff here" download="filename here">. It isn't very widely supported yet though.
Another alternative would be to first submit the data to the server using ajax, then redirect the browser to some server-side script which would then serve the data with the correct header.
Hi i have created a jquery plugin which will let you do the same task with ease but it also make use of php to download the image. let me explain how it works
Plugin has 2 sub function that you can call independently to add image to the canvas and the other one is to download the current image lying on the canvas.
Add image to the canvas
For this you need to pass the id of the canvas element and the path of the image you want to add
download image from the canvas
For this you need to pass the id of the canvas element
$('body').CanvasToPhp.upload({
canvasId: "canvas", // passing the canvasId
image: "455.jpg" // passing the image path
});
// downloading file
$('#download').click(function(){
$('body').CanvasToPhp.download({
canvasId: "canvas" // passing the canvas id
}); //
});
First you need to download the plugin file which you can find here http://www.thetutlage.com/post=TUT213
I have also created a little demo http://thetutlage.com/demo/canvasImageDownload

Categories