What Does This Mean and How Does It Help? - javascript

At the moment I'm coding a web application that imports image data from Google Maps via the Static API - http://code.google.com/apis/maps/documentation/staticmaps/ - into an HTML5 canvas.
Unfortunately, I've run into the problem of not being able to manipulate the pixel data from Google Maps due to cross domain restrictions.
However, I've been reading this blog post by Mr. Doob, one of the people behind the Wilderness Downtown video ( http://thewildernessdowntown.com ) which employs canvas with Google Maps - http://mrdoob.com/blog/post/705 - and it reads:
"An additional challenge was that with you don't have access to the pixel data of images loaded from another domain...However, albeit pixel access is forbidden, context.drawImage() is allowed for copying areas from images hosted on other domains."
I feel this may be the solution to my problem as later in the post it shows pixel manipulation of the image, but I don't quite get what exactly it means by 'context.drawImage() is allowed for copying areas from images hosted on other domains' and it would be really helpful if someone could clarify it for me.
Thanks,
DLiKS
Edit: Here is the code I'm using to draw the Google Maps image to the canvas:
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = 'LINK TO GOOGLE MAPS IMAGE';
img.onload = function(){
ctx.drawImage(img,0,0);
}
The image displays OK but when I try to use getImageData to manipulate this embedded image on the canvas, I get a security error

Having read the article I think you misinterpreted what Mr.doob said:
"[Jamie] then started researching other ways of drawing the Maps Data in a way that would create the same effect."
He does no pixel manipulation, he uses context.drawImage for
"...cropping columns from the original image and positioning them one after the other horizontally."

Assign src to image using one aspx page, and that aspx page will respond with your text to the image.
For example:
image.src="CreateImage.aspx";
image.onload = function () {
ctx.drawImage(image,5,5,width,height);
}

context.drawImage() i believe is some way of manipulating a HTML 5 Canvas.
Take a look at these webpages.
http://dev.opera.com/articles/view/html-5-canvas-the-basics/
http://diveintohtml5.ep.io/canvas.html

Related

Is it possible in JavaScript to create a div, put a \u#### character in that div, then copy to canvas as a putImage?

I am working with fTelnet.js - I have gotten down to the this_Font.GetChar() code and have found all characters are from a Font Sprite, it getItemData(....) changes the color where The pixel is 0x80 and colors it foreground [r][g][b][alpha], or colors it background [r][g][b][alpha].
Since Unicode goes outside what is in its 40+ fonts - I need to cheat and .createElement("div"), .innerHTML = "\u#####"; then somehow take that as ImageData so I can patch the above logic and introduce unicode support to fTelnet's canvas routine.
Does anyone know what command(s) I am needed to do this? e.g. I have spent hours trying to resolve this via Google, HTML5 Context docs, without success... mainly not knowing what I am searching for ;-)
or as I re-read this... maybe a hidden canvas, do the ctx.strokeText("\u#####", 25, 50); and then copy from that CTX as a IMAGEDATA to the displayed? (what command would I look up then?)... I normally do not dabble in 2D/3D graphics world (obviously)...
Regards,
Generally, rendering HTML to canvas is not possible - and that seems to be by design (it would make issues like tainting much harder to navigate).
But stamping one canvas on top of another is simple - you can just use the standard #drawImage call, same as with any other image you would draw on canvas.
Actually, if you look at the API documentation and click through the definitions you will see that you can use drawImage to "stamp" any instance of svg or html image, a bitmap, offscreen canvas, video or audio tags.

Weird compression of html image

I want to use a base64-encoded png that I retrieve from a server in WebGL.
To do this, I load the encoded png into an html Image object.
For my application, I need the png data to be absolutely lossless, but the retrieved pixel values by the shader are different in different browsers...
(if I load the Image into a canvas and use getImageData, the retrieved pixel values are different across browsers as well).
There must be some weird filtering/compression of pixel values happening, but I can't figure out how and why. Anyone familiar with this problem?
Loading the image from the server:
var htmlImage = new Image();
htmlImage.src = BASE64_STRING_FROM_SERVER
Loading the image into the shader:
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGB, ctx.RGB, ctx.UNSIGNED_BYTE,
htmlImage);
Trying to read the pixel values using a canvas (different values across browsers):
var canvas = document.createElement('canvas');
canvas.width = htmlImage.width;
canvas.height = htmlImage.height;
canvas.getContext('2d').drawImage(htmlImage, 0, 0, htmlImage.width,
htmlImage.height);
// This data is different in, for example, the latest version of Chrome and Firefox
var pixelData = canvas.getContext('2d').getImageData(0, 0,
htmlImage.width, htmlImage.height).data;
As #Sergiu points out, by default the browser may apply color correction, gamma correction, color profiles or anything else to images.
In WebGL though you can turn this off. Before uploading the image to the texture call gl.pixelStorei with gl.UNPACK_COLORSPACE_CONVERSION_WEBGL and pass it gl_NONE as in
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
This will tell the browser not to apply color spaces, gamma, etc. This was important for WebGL because lots of 3D applications use textures to pass things other than images. Examples include normal maps, height maps, ambient occlusion maps, glow maps, specular maps, and many other kinds of data.
The default setting is
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL);
Note this likely only works when taking data directly from an image, not when passing the image through a 2d canvas.
Note that if you're getting the data from WebGL canvas by drawing it into a 2D canvas then all bets are off. If nothing else a canvas 2D uses premultiplied alpha so copying data into and out of a 2D canvas is always lossy if alpha < 255. Use gl.readPixels if you want the data back unaffected by whatever 2D canvas does.
Note that one potential problem with this method is speed. The browser probably assumes when you download an image that it will eventually be displayed. It has no way of knowing in advance that it's going to be used in a texture. So, you create an image tag, set the src attribute, the browser downloads the image, decompresses it, prepares it for display, then emits the load event, you then upload that image to a texture with UNPACK_COLORSPACE_CONVERSION_WEBGL = NONE. The browser at this point might have to re-decompress it if it didn't keep around a version that doesn't have color space conversion already applied. It's not likely a noticeable speed issue but it's also not zero.
To get around this the browsers added the ImageBitmap api. This API solves a few problems.
It can be used in a web worker because it's not a DOM element like Image is
You can pass it a sub rectangle so you don't have to first get the entire image just to ultimately get some part if it
You can tell it whether or not to apply color space correction before it starts avoiding the issue mentioned above.
Unfortunately as of 2018/12 it's only fully supported by Chrome. Firefox has partial support. Safari has none.

Unable to get Sprite maps to work correctly in THREE js

I am simply trying to add a sprite to my scene normally. I am using this image: i.imgur.com/kMT4mOH.png
var map = THREE.ImageUtils.loadTexture('i.imgur.com/kMT4mOH.png');
var mat = new THREE.SpriteMaterial({map:map, color: 0xff5200, fog: true, blending: THREE.AdditiveBlending});
var glow = new THREE.Sprite(mat);
scene.add(glow);
However when I add color to the sprite, the entire image turns the color instead of just the white space.
Here is a jsfiddle: http://jsfiddle.net/VsWb9/2331/
Im not entirely sure what Im doing wrong and any help would be appreciated.
The image is not loading because the url to the image is i.imgur.com/kMT4mOH.png. So the page is searching for the file on locally. ie. http://fiddle.jshell.net/VsWb9/2331/show/i.imgur.com/kMT4mOH.png.
To get the file from its external location you would use http://i.imgur.com/kMT4mOH.png, but you then get the problem of cross domain restrictions on webgl textures, so this will also not work also.
I don't see any problem with your code so if you run it from a server where the texture image and the image file are both on the same server, it should work.
Read more about cross domain webgl images at: http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
There seems there may be a work around if you really need it to work in a jsfiddle, it is outlined on this other stackoverflow question: cross-domain image for three.js (canvas/webGL), proxy?

How to take a snap of an HTML5 canvas when it contains image as an object

I have made a canvas and added different objects to it such as images, clipart and text. When I take snap of the canvas when it contains only text, using the method canvas.toDataURL(), it gives me the correct snap. But when I add an image to the canvas, it will return a blank page.
My code is as follows:
canInstance.discardActiveObject();
drawCanvas.loadFromJSON(json,function(){
var img = drawCanvas.toDataURL("png");
$("#previewPopUp").append("<img src='"+ img +"'/>");
});
I am using fabricjs. Can anybody tell how to take a snap of a canvas when it contains a image?
The likeliest reason why it doesn't work is because you are loading the image from a different domain than where your HTML is hosted. As soon as you do that, the canvas gets "tainted by cross-origin data" and certain functions which allow to read the canvas content become unavailable.
This is a security feature to prevent web developers from accessing images only the user is allowed to access.
As a workaround, copy the image to the same domain or, when you control the domain the image is loaded from, whitelist the domain with your HTML by enabling Cross-Origin Resource Sharing in the settings of the webserver.

Capture/save/export an image with CSS filter effects applied

I'm tooling around to make a simple picture editor that uses CSS3 filter effects (saturation, sepia, contrast, etc.)
Making the picture editor is the easy part, however whether it is possible to save or export the image with the filters applied seems incredibly difficult..
I had originally had high hopes it would be possible with #niklasvh's html2canvas. Unfortunately, it doesn't capture most CSS3 properties, let alone filter effects.
If anybody has a solution or sadly, definitive knowledge that this just isn't possible, it would be greatly appreciated! Thanks!
You're not, that I'm aware of, able to apply CSS to graphics in the HTML5 canvas element (as they're not a part of the DOM).
However, that's OK! We can still do basic filter effects relatively easy and save them out as an image with just a few lines of JavaScript.
I found a good article that goes over applying a sepia-like effect to the canvas and saving it as an image. Rather than copying it, I'll highlight the larger takeaways from the article.
Modifying the canvas image:
var canvas = document.getElementById('canvasElementId'),
context = canvas.getContext('2d');
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
for (var i = 0; i < imageData.data.length; i+=4) {
...
}
In order to get access to some canvas API, you'll need to activate the 2d context on the canvas using the above JavaScript. MDN has some great documentation on the API that is available to you with the context object, but the important part to note here is the getImageData() call. Basically, it will grab all the pixel values in the area that you defined (in the case above, we're grabbing the whole image). Then, with this data in hand, we can iterate through all the pixels and change them as needed. In the sepia article, it's obviously making some interesting adjustments, but you can also do grayscale, blurring, or any other changes as necessary and there's an awesome canvas filters library on Github for just that.
How to save the canvas image:
var canvas = document.getElementById('canvasElementId'),
image = document.createElement("img");
image.src = canvas.toDataURL('image/jpeg');
document.body.appendChild(image);
The above script will select your canvas (assuming you've already done your drawings) and create an image element. It them uses toDataURL() to generate a url that you can use to set the source on an image element. In the example above, the image element is appended to the document body. You can view more info on MDN's canvas page.
I got your answer.
I made this program, finally it's work.
those step is :
1. upload the image (JPG/PNG)
2. convert to canvas
3. custom with css filters.
4. render using camanJS to save as image.
5. done.
you also can reset effect value by modifying value of filters to its default.
good luck!

Categories