Pixel level access with Pixastic and RaphaelJS - javascript

I'm working on an image editor and I have to create some pixel manipulation methods applied on RaphaelJS images. I am considering using Pixastic library for pixel manipulation.
The problem is the I cannot link RaphaelJS image to Pixastic since RaphaelJS creates a SVG element and Pixastic requires an 'img' tag.
I have tried something like this but with no success
img = r.image("Assets/test.jpg", 40, 40, 260, 150);
img.node=Pixastic.process(img.node, "desaturate");

There's not really currently an easy way to do this. As mentioned already, in many browsers you can output to Canvas and then perform pixel-level transformations, but this transition from SVG to Canvas is destructive, as you have gone from a retained-mode context to an immediate-mode context, and you therefore lose all the niceties of the retained mode API, such as being able to register event listeners on individual shapes, or have a high-level API for transforming individual shapes (or groups of shapes).
However, if you don't need the element-level event handling, you might look into the dojox.gfx library, which provides a high-level, retained-mode, SVG-inspired API for drawing shapes, but also has a Canvas backend (VML and Silverlight too). I believe it is not possible to register event listeners on individual shapes when using the Canvas output, but you would be able to register an event handler on the root canvas element. It might be possible to then apply transformations with Pixtastic, but you might need to hack into the dojox.gfx Canvas render code a bit.
You might also look into SVG filters, which is as close to native support for pixel-level, raster graphics-style manipulation as it gets with SVG.
I also believe they're currently trying to combine the two specifications somewhat to make such work possible: http://lists.w3.org/Archives/Public/public-canvas-api/2011AprJun/0117.html

You could try drawing the svg to a canvas element check near the end of this article https://developer.mozilla.org/en/drawing_graphics_with_canvas. Then outputting the canvas to a base 64 encoded image. Not having worked with either RaphaelJS or pixastic I am not sure how well this would work.

Related

How does context.drawImage work

In HTML5, using the canvas object you can draw an image.
context.drawImage(imageObj, x, y);
How does this work under the hood? Is the browser drawing pixels or using svg? I do not see any svg elements being added to the dom, so I am assuming the browser is drawing pixels, but how does it accomplish this all? Is there a library that the browser is using?
For the sake of discussion I guess we could just consider Webkit, but I would also be interested in what other browsers (IE) do.
Canvas is a pixel-based interface, SVG is a markup-language for vector graphics, they are two very separate things.
If you add an image to canvas it loads it first into the dom and then renders it to the canvas.
You can use SVG in conjunction with Canvas though. Say you wanted your canvas app to scale, you could simply rerender your svg files in different sizes to the canvas like described here
Because SVG-graphics can be used like images, they can just be rendered onto canvas like images.
If you want to have more in depth knowledge about canvas just read the spec
Well...you asked!
Think of canvas as a big, living bitmap...and here are the details:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html

HTML5 SVG vs Canvas for big number of lines?

Question:
Is canvas more suitable than svg in the following case?
Case:
I'm drawing a chart (using d3js library) similar to this one (but with much more data):
http://mbostock.github.com/d3/talk/20111116/iris-parallel.html
It's based on an svg and it works fine for several thousands of lines (up to 5000), adding more lines (svg path) decreases the performance dramatically (scrolling in the page becomes slow)
Keep in mind: That I need to add mouse events (which is handy in svg)
Generally svg is better suited for vector images, like in your example. However canvas has a lot of benefits in modern browsers such as hardware acceleration, so for drawing the lines, as long as zooming, panning ect. isn't required performance will be using canvas.
Mouse events can be a pain using canvas, since you have to manually keep track of everything, so with 5000+ points using canvas it wont be fun. The trade off however will be once the points are drawn, assuming you only draw them once the page will behave fine regardless of the number of lines, since they are all drawn to a raster image and aren't part of the DOM.
Honestly though the best way to find it is to test what you currently have using canvas.
When performance becomes a problem, switching to canvas might be an option. In this case you can draw the canvas once. Afterwards it's pretty much treated like an image. Drawing might take some time, but afterwards it can be scaled pretty quickly. Note that it is possible to draw a rendered SVG to a canvas using the context.drawImage method (example). So you could keep your SVG generation code to create an SVG in the background, and then draw it to the canvas.
But keep in mind that it won't scale as beautiful as an SVG as soon as it is on the canvas. When the user zooms in, it will get blurry or pixely, depending on how the browser scales graphics.
Click events on canvas can be handled in two ways. Either keep an array of click targets, and add an onclick event handler to the canvas. When a click occurs, iterate the array and check which one is closest to the click coordinates.
The other option is to use hit regions. These have to be defined as polygonal paths.
+1 to everything said above. I've seen some amazing performance increases when using canvas over SVG and over compositing images using the DOM.
About manipulating the canvas image with mouse events, I imagine the best approach for an image such as you are describing is to abstract it away using a library like the following:
http://paperjs.org
http://kineticjs.com
http://www.createjs.com/#!/EaselJS
Keep your code away from the canvas itself and let a library do the thinking for you.

Replacement for SVG

My project is using SVG and there is a plan to move out of SVG and replace the existing functionality with suitable replacement.
My current SVG apps does following things,
1. Exposes the object(SVG shapes) relations or dependency in screen.
When there are two dependent shapes (say rect1 and rect2), we draw a line from rect1 to react2 to say that they are dependent.
2. Triggers javascript functions when we fire certain events (click or mouse over) on shapes.
Is there any alternatives to replace the SVG and simply the drawing process?
I am thinking to store the shapes information in database and auto generate the shapes in UI.
Thanks in advance.
What about using canvas from HTML 5. Consider client browsers version when decide to use canvas.

Pie, bar, line: SVG/VML better than Canvas

I need to choose a library for "standard" charting: pies, lines and bars.
From what I've read, it seems to me that the best format is SVG/VML, like Highcharts for example. SVG is becoming standard across all major browsers, now that IE 9 accepts it. It seems easier to rescale and export than Canvas.
Still, I see that several charting libraries rely on Canvas. Am I missing something? Is there any reason for considering Canvas over SVG for such applications?
You can generally achieve the same results with either. Both end up drawing pixels to the screen for the user. The major differentiators are that HTML5 Canvas gives you pixel-level control over the results (both reading and writing), while SVG is a retained-mode graphics API that makes it very easy to handle events or manipulate the artwork with JavaScript or SMIL Animation and have all redrawing taken care of for you.
In general, I'd suggest using HTML5 Canvas if you:
need pixel-level control over effects (e.g. blurring or blending)
have a very large number of data points that will be presented once (and perhaps panned), but are otherwise static
Use SVG if you:
want complex objects drawn on the screen to be associated with events (e.g. move over a data point to see a tooltip)
want the result to print well at high resolution
need to animate the shapes of various graph parts independently
will be including text in your output that you want to be indexed by search engines
want to use XML and/or XSLT to produce the output
Canvas isn't needed unless you want heavy manipulation/animation or are going to have 10,000+ charts. More on performance analysis here.
It is also important to make the distinction: Charting and diagramming are two different things. Displaying a few bar charts is very different from (for instance) making diagramming flowcharts with 10,000+ movable, link-able, potentially-animated objects.
Every SVG element is a DOM element, and adding 10,000 or 100,000 nodes to the DOM causes incredible slowdown. But adding that many elements to Canvas is entirely doable, and can be quite fast.
In case it may have confused you: RaphaelJS (in my opinion the best charting SVG Library) makes use of the word canvas, but that is no way related to the HTML <canvas> element.
In the past two years, my preference has been to use svg, as I mainly deal with relatively small datasets to build pies, column charts or maps.
However one advantage I have found with canvas is the ability to save the chart as an image thanks to the toDataURL method. I haven't found an equivalent for svg, and it seems that the best way to save an svg chart client side is to convert it to canvas first (using for example canvg).

Choosing right technology (SVG vs Canvas)

I'm writing an app for shape manipulation, such that after creating simple shapes the user can create more complex ones by clipping the shapes against each other (i.e. combining two circles together into a figure 8 stored using a single path rather than a group, or performing intersection of two circles to create a "bite" mark), and am trying to decide on a graphics library to use.
SVG seems to handle 80% of the functionality I need out of the box (shape storage, movement, rotation, scaling). The problem is that the other 20% (using clipping to create a new set of complex polygons) seems impossible to achieve without recreating SVG functionality in my own modules (I'd have to store the shape once for drawing inside SVG, and once for processing clipping myself). I could be wrong about SVG, but by reading about Raphael library (based on SVG), it seems like it only handles clipping using a rectangle, and even that clipping is temporary (it only renders part of the shape, but still stores entire shape to be rerendered once the clipping rectangle is moved). Perhaps I'm just confused about SVG standard, but even retrieving/parsing the paths to compute a new path using subsets of previous paths seems non-obvious in SVG (there is a Subpath() function, but I don't see anything to find the points of intersection of two polygon perimeters, or combine several subpaths into a single path).
As a result, Canvas seems like a better alternative since it doesn't introduce the extra overhead by keeping track of shapes I'd already have to keep track of to make my own clipping implementation work. Not only that, I've already implemented the polygon class that can be moved, rotated, and scaled. Canvas has some other issues, however (I'd have to implement my own redraw method, which I'm sure will not be as efficient as SVG one that takes advantage of browser-specific frameworks in Chrome and Firefox; and I'd have to accept IE incompatibility which is handled for free with libraries like Raphael).
Thanks
This may address what you're mentioning.
Clipping can be done using non-rectangular objects using the 'clipPath' element.
For example, I have element with id of 'clipper' that defines what to clip out, and a path that is subject to the clipping. Not sure if they intersect in this snippet.
<g clip-rule="nonzero">
<clipPath id="clipper">
<ellipse rx="70" ry="95" clip-rule="evenodd"/>
</clipPath>
<!-- stuff to be clipped -->
<path clip-path="url(#clipper)" d="M-100 0 a100 50"/>
</g>
This is just a snippet from something I have. Hope it helps.
Seems to me that you are trying to do 2D constructive geometry. Since SVG runs in retained mode, the objects you draw are stored and then the various operations performed. With Canvas you are running against a bit map so the changes are effected immediately. Since your users will in turn perform more operations on your simpler shapes to create ever more complex ones Canvas should in the long term be a better fit.
The only outstanding question is what will be done with those objects once your users are finished with them. If you zoom the image it will get the jaggies. SVG will avoid that problem but you trade-off with greater complexity and performance impact.
Both svg and canvas are a vector graphical technology.Each one having some different functionality.
Canvas
Canvas is a bitmap with an immediate modegraphics application programming interface (API) for drawing on it. Canvas is a “fire and forget” model that renders its graphics directly to its bitmap and then subsequently has no sense of the shapes that were drawn; only the resulting bitmap stays around.
More Information about canvas - http://www.queryhome.com/51054/about-html5-canvas
SVG
SVG is used to describe Scalable Vector Graphics
SVG is known as a retained mode graphics model persisting in an in-memory model. Analogous to HTML, SVG builds an object model of elements, attributes, and styles. When the element appears in an HTML5 document, it behaves like an inline block and is part of the HTML document tree.
More Information about SVG - http://www.queryhome.com/50869/about-svg-part-1
See here for more information about canvas vs svg in detail - Comparing svg vs canvas
You're right - you'll have to mathematically perform the clipping and creation of new shapes regardless of whether you use SVG or Canvas. I'm biased, it seems like it would be more useful to use SVG since you also get things like DOM events on the shapes (mouse, dragging) and serialization into a graphical format for free.

Categories

Resources