I am looking for a way to use HTML5 canvas element to display an image of floats. Consider a grey scale image where values are not 8-bit nor 16-bit integers but are floats (or doubles). I would like to have a javascript/html5 solution to display the image inside the browser using a colormap. Additionally, I would like the user to be able to adjust interactively the minimum and maximum value.
This operation is quite common in scientific imaging software such as ImageJ but I haven't found a javascript/html5 solution. Pixastic seems to be in the right track for this but is more oriented to color image processing.
Any ideas, thanks in advance
I think I had the same need for work.
First i would say that I don't offer a library solution but I tell you how I code this.
I choose to make the colormap canvas using canvas linear Gradient.
To apply this gradient on my picture, I simply calcul the min/max of value I need to represent, then I searched for each values what colors correspond considering my linear gradient.
My picture has been included in a canvas using drawImage.
Then I changed the color of each pixel using canvasPixel manipulation on data array.
For interactive move colormap I choose to use JqueryUi slider.
All of this is linked on my code and it was a bit long to do.
Well I added some more complicated stuff because user is able to modify the color of linearGradient using a colorPicker Jquery plugin but it's more or less what you want too ?
I hope I answer your question. Good luck.
Related
Is there a way to alter and replace the color palette of an indexed image with JavaScript?
I am aware that I can draw the image to a canvas, iterate through each pixel of the image, and overwrite pixels individually. However, that seems like overkill to me, and I would like a cleaner solution.
I would be willing to use a library to accomplish this. Additionally, I am working with pretty small images, so the "overkill" method which I previously mentioned would not be infeasible if necessary.
Before an alpha colour channel existed sprites in games often had a mask colour, which was a predefined value that wouldn't be displayed. Many spritesheets have an arbitrary background colour, which I want to be able to mask using Javascript canvas.
So far I haven't been able to find a way to do this in the documentation and when I search for colour masking the results seem to relate to clipping an image with a stencil image or SVG, which is not what I'm after.
One way I could do achieve what I want to do is by reading each pixel value, checking the RGB value and if it matches set the alpha for that pixel to 0. The problem with that approach is that it would be unbearably slow in Javascript. What would be a faster/better way to mask a specific colour on an image?
The fastest and best way is to use an image format that does support transparency like webp or png.
Assets should be prepared only once by dedicated tools, not every time someone will use your app.
I am looking to achieve something like this. A HTML view has a finite number of images (shown as red boxes in the image below). Are there any browser/jQuery APIs available today (cross-browser) which will let me calculate the dimensions of the remaining space (shown in green boxes) quickly? In the example shown below, it is easy to calculate the green area dimensions using simple geometry given the dimensions of the red boxes. But I am talking about very complex scenarios and complicated combination of images.
Appreciate any help. Thanks.
If you every images have absolute property, you can calculate dimension through top and left properties like $('#elementID').offset().top and $('#elementID').offset().left
From my experience working with DOM element dimensions, you cannot rely on them for exact values, and certainly can't really on them for the same values cross-browser. You can get OK results, but if you have complex scenarios then you will probably come undone at some point.
One way I have achieved similar things in the past is by drawing images to HTML5 Canvas. Using canvas you can have very fine-grained control. I have even iterated canvases pixel-by-pixel to get pixel perfect measurements of items on the canvas.
Check out this tutorial for a brief overview of drawing an image.
UPDATE
There is no easy way to do it. Using this method is low-level and will require you to use mathematics, and possibly byte-level image data from the canvas. However, if your problem is as complex as you suggest then you will have to get stuck in. When I did something similar I was also looking for an easy way to achieve what I wanted in the browser, then spent a month getting to grips with the canvas API, learning about byte-level colour data etc, but in then end I got what I needed, and ended up with something quite unique as it was difficult to achieve in a browser.
To get started, first I would say look at implementing a layered canvas by absolutely positioning multiple canvases on top of each other, then drawing a single image on each one. You already know the sizes of the images, and you can decide the coordinates of where to draw the image, so that's a start. In fact that may be all you need, you can track each image as you draw them by storing coords and dimensions, and you should be able to build up an accurate picture in numbers of where all your images are in 2D space.
Using those numbers you should then be able to calculate any empty spaces on there. However, that is a beyond me and probably a question for Mathematics Stack Exchange (which is actually down at the moment :D).
I'm creating a planning tool for a game. Imagine two 2D static gun emplacements with different ranges and damage per second. I want to draw these ranges with different colours according to damage, in a scale similar to this http://www.celtrio.com/support/documentation/coverazone/2.1.0/ui.viewmode.heatmapcolorscale.html
I got that part working with CSS border radiuses. My problem is that if ranges overlap, the overlapping area doesn't show the combined damage.
I found heatmap.js http://www.patrick-wied.at/static/heatmapjs/ but it doesn't allow you to set a different radius for each point. I also can't find a way to turn off the gradient... the damage of these guns at its maximum range is the same at its minimum range. I realise that's sort of the point of a heatmap normally haha but I'm not too sure what I should be googling.
I had a think about a PHP solution which would create a greyscale image using varying levels of opacity to represent different damage. I'd then loop through all the pixels and recolour them according to the scale. But that would be far too slow. It needs to update in as close to realtime as possible as the user drags the guns around the screen.
There's probably a very simple way to do this, a CSS filter maybe, but I can't find anything. Any ideas? Thanks!
CSS is the wrong tool for this job -- you really ought to be doing stuff like this using SVG or Canvas. It'll be a lot easier to achieve complex graphical effects using a proper graphics system than trying to hack it with shapes created in CSS.
For example, in SVG, you would simply need to use the fill feature to fill each area with whatever colour you wanted. See an example SVG image here. It's an SVG Venn diagram where the overlap areas are completely different colours to the parent circles. Canvas has similar functionality.
You might also want to consider using a Javascript library such as RaphaelJS or PaperJS to help you with this. (using Canvas would imply that you're using some Javascript anyway, and it will make SVG easier to work with too).
However if you must do it using CSS, if you want elements to show through so the colours are merged when they overlay each other, then you'll want to use some sort of opacity effect.
Either opacity:0.5 or an rgba colour for the background.
That's as good as you'll get with CSS; you won't be able to get arbitrary colours in the overlap portions; just a combination of colours from the layered opacity effects.
If you look at the code of heatmap.js, you'll see that it works like this:
Paint circles onto a canvas, using a radial gradient from transparent to some percent opaque (depending on the strength of the point).
Color-map that grayscale image (converting each gray value to one of an array of 256 colors).
Your problem could be solved in the same way, but painting a circle of constant opacity and variable radius in step 1.
I'm trying to implement collision detection for SVG text elements using client side JavaScript. The hit-test should check if any glyph of a text overlaps any glyph of another text element. Since getBBox and getExtentOfChar are anything than accurate I need a custom solution.
My first approach was to get the colour of each coordinate/pixel of an element and do the hit-testing manually, but this does not work because it isn't possible to get the colour of a coordinate. It would require an additional canvas to get pixel colours -> awful workaround.
Now I'm thinking about converting the text or the glyphs to polygons for hit testing. Is it possible? Or has anyone another approach for glyph based hit testing?
Best Regards
You are really entering a world of pain and cross browser problems. I ended up doing custom path-rendering of fonts only to get the total text length reliable and consistent. I don't even want to think about glyph-hitting.
One problem for example is that firefox (at least 3.6) and iirc also some version of opera has some rounding error when scaling so when you scale the parent-element holding the text and scale the text by the inverse of that scale, then the letter-spacing will be slightly different compared to without any scale. (Because each letter must begin on an even number or something like that, problem can be solved by multiplying both the upscale and downscale with like 10000 but that's another story)
The performance impact by using path compared to text is unfortunately quite noticeable. If your canvas does any form of animated panning or zooming you should switch to pure text-elements during the animation and once static, turn on path rendering for accuracy.
Fortunally converting svg-fonts to paths is very easy, it is plaintext and using the exact same format as the path-element. (beware of font-embedding-licenses though! Also keep file size in mind as you cannot use the fonts from the users system, )
As for the pixel-based hit-testing – if you switch to HTML5 Canvas, then this will become possible. Several projects provide easy transition from SVG to Canvas, e.g. fabric.js. See a comparison table here.
As for the polygon-based approach – possible, but difficult. You can convert text or glyphs to polygons (paths) using some tool (Inkscape's text-to-path for instance). And then there'll be calculations. Making a general solution for any text will require a lot of work. However, if the text doesn't change, then drawing your text manually using paths can be a quick and dirty solution.