I want to draw a polygon/polyline on to a big image.
So, I am migrating from PIL/opencv to pyvips. Recently, I came across loadsvg_buffer method that can actually do it without the use of draw_mask and draw_image methods.
Can someone give me one fill example using loadsvg_buffer or draw_mask or draw_image. The documentation wasn't much helpful.
Also, what if I have to draw multiple polylines?
Any other insights are welcome.
svgload docs are here:
https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-svgload
You can draw any SVG figure. For example:
import pyvips
x = pyvips.Image.svgload_buffer(b"""
<svg viewBox="0 0 200 200">
<circle r="100" cx="100" cy="100" fill="#900"/>
</svg>
""")
x.write_to_file("x.png")
To generate:
The libvips SVG loader is very fast and can make images of any size. It renders progressively, so it doesn't need much memory either.
Use the boolean operators to mask other images with the result, or use composite to layer images together with the PDF blend modes.
Related
I am a beginner in SVG.
I need an SVG curve that passes through a list of points. It is a math function that is calculated in C++ and the output result is supposed to be written in an SVG file. My problem is that the path tag in SVG does not pass through all points. Instead, it skips some of them in the middle and just tends to them. Does SVG have any facility to pass the curve through the whole points and bend the curve appropriately in automatic way?
<svg height="400" width="450">
<path d="M 80 90 C 190 40, 300 60, 380 160" stroke="blue" stroke-width="5" fill="none" />
<path d="M 80 90 L 190 40, 300 60, 380 160" stroke="green" stroke-width="1" fill="none"/>
<g stroke="black" stroke-width="3" fill="black">
<circle id="pointC" cx="80" cy="90" r="3" stroke="black"/>
<circle id="pointA" cx="190" cy="40" r="3" stroke="green"/>
<circle id="pointC" cx="300" cy="60" r="3" stroke="red"/>
<circle id="pointB" cx="380" cy="160" r="3" stroke="blue"/>
</g>
Sorry, your browser does not support inline SVG.
</svg>
If you need to draw smooth curve through many points, considering using Catmull Rom splines or Overhauser splines. Both algorithms will result in a cubic spline with C1 continuity at the segment junctions. Also, they are easier to implement than implementing C2 B-spline interpolation as the latter requires you to solve a linear equation set. You can also convert Catmull Rom spline or Overhauser spline back to Bezier form easily.
in SVG path thee Bezier curve is approximation not interpolation so it is usually not passing through all the control points.
Sp what to do:
use interpolation cubic curve and convert it to Bezier
Look here: Interpolation cubic to Bezier cubic (needed this for similar reasons like you)
I use a specific interpolation cubic there with connectivity C1 (position and 1st derivation) the translation to Bezier is there so you can use it just convert the control points ... Do not forget to 3x multiple only first and last control point for the whole Bezier path not for each Bezier patch !!!
use many lines instead of single Bezier
this will be choppy of coarse (depending on the lines density) just interpolate enough points and connect them by lines
duplicate control points
if you have multipled control points (3x) then the Bezier will go through this point. So if you have curve points: p0,p1,p2,p3,... then do multiple Beziers from them like this:
p0,p0,p0,p1
p0,p0,p1,p2
p0,p1,p2,p3
p1,p2,p3,p3
p2,p3,p3,p3
p3,p3,p3,p4
p3,p3,p4,p5
p3,p4,p5,p6
p4,p5,p6,p6
p5,p6,p6,p6,...
this will go through the points p0,p3,p6,... so you still need to evaluate the non passing control points to ensure desired connectivity
If you need to draw curve through 4 points only, look at the solution in this topic and linked tinaja page.
If you have to draw smooth curve through many points, consider building interpolation cubic splines (NR book, page 113), than transform these splines to Bezier form (change bazis from polynomial to Bernstein)
I need your help , I am confused a little.
My question is how SVG curveTo works, really I can't understand.
look for this example
<svg height="400" width="400">
<path d="M 200 90 C 200 90 0 0 90 300 " stroke="black" fill="none" stroke-width="3"/>
</svg>
this code draws this shape
but really I can't understand how that done , I can't understand how the curve identified and what control points are and what 0 0 coordinate represents in my example.
You are drawing a Cubic Bezier curve (with two control points). But one of the control points has the same coordinates as the starting point.
Move (M) to (200,90).
Draw a Cubic (C) Bezier Curve
a. starting at current position (200,90)
b. first control point at (200,90) - same as starting point
c. second control point at (0,0)
d. ending at (90,300)
Bezier curves are a bit tricky to get the sense of. Perhaps the section at http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#path_C might help, and maybe the section before that on quadratic Beziers. As the earlier poster pointed out, having your start point and the control point coincident makes your case a bit odder, still, perhaps.
I've grabbed some code from somewhere to create an interactive UK map using SVG.
You can see it here:
I'm wondering how I can get the blue area into one big polygon as opposed to separate areas. Any help would seriously appreciated!
Many thanks in advance.
You can group the smaller polygon paths like
<g id="England">
<path .... />
<path .... />
<path .... />
</g>
and then treat them as 1 larger polygon for the purposes of color fill and click area. If you want to remove the inner borders just set the stroke to the same color as the fill.
The only thing you can't do is stroke the outer group since it itself doesn't have a shape, its just the collection of the inner shapes and theres no way to just stroke the edges that do not border another group member. For that you probably would need to actually merge the polygons, which might be easier to do in Inkscape or Adobe Illustrator
See my example here where I've grouped the western US states. Click anywhere in the group to change the color. In the svg(html panel) code, the CA-WA-OR are the last 3 paths at the bottom...
http://jsfiddle.net/webchemist/K9jdD/
Get the original geographic data file in a 'shapefile' or other geospatial data format, load into a GIS package (Quantum GIS is free, open source, and featureful) then do a polygon dissolve operation.
You can also do this with the GEOS library which has an interface to C, Python and R if you can program in any of those languages.
these vector or raster files being classic files without geocoordinates. They are lat/long projection, I want to import them into QGIS, scale them up/down, place them to their right place, and they become reusable shp or raster geocoordinated layers.
Edit: I'am from the wikipedia Graphic Lab>Map workshop, we want to work more using GIS. We litteraly have hundreds maps to migrate to GIS technologies....
File:Chinese_plain_5c._BC-en.svg
File:Vignobles_basse_loire.svg
Partial Solution: load SVG into Inkscape, Save as DXF file, then you can load this into QGIS. This should at least get you most of the linework into QGIS.
However, it won't yet be properly georeferenced or styled, and different layers may be in different places because the SVG has some scaling and translating operators on parts of the map data that QGIS or Inkscape is ignoring. You'll probably need to work with a layer at a time. This probably isn't a problem since maybe you are only interested in the added data on the map, and not the base map (country outlines etc) since you will probably want to overlay your data onto standard map base layer (natural earth, OpenStreetMap tiles).
The only way I see to do the transformation at present is to work out the affine transformation parameters and use the QgsAffine plugin, but that does require you to work out the parameters beforehand by fitting known source coordinates to known target coordinates.
But to do hundreds? You might be better off writing some custom SVG parsing code for each one...
If you only want to display it in the correct place, scale and rotation treat it as an SVG icon.
1. create a point layer and put a single point at the georeferenced centre of the SVG you will load.
2. edit the symbology and load the SVG as an icon
3. set the size units to map units
4. supply the appropriate dimensions
5. rotate as necessary
The redraw is very slow and painful, but if you use Project>import/Export>Export map as image you can make a georeferenced raster.
How to blur 3d object? (Papervision 3d) And save created new object as new 3d model? (can help in sky/clouds generation)
Like in 2d picture I've turn rectangel intu some blury structure
(source: narod.ru)
Set useOwnContainer to true the add the filter:
your3DObject.useOwnContainer = true;
your3DObject.filters = [new BlurFilter(4,4,2)];
When you set useOwnContainer to true, a new 2d DisplayObject is created to render the 3d projection into, and you can apply of the usual DisplayObject properties to that.
Andy Zupko has a good post about this and render layers.
Using this will cost your processor a bit, so use it wisely. For example
in the twigital I worked on at disturb media we used one Glow for
the layer that holds all the characters, not inidividual render layers for each
character. On other projects we 'baked' the filters into bitmaps and used them,
this meant a bit more memory, but freed up the processor a bit for other tasks.
HTH
I'm not familiar with Papervision 3D, but blurring in 3D is normally just blurring in 2D. You pick the object you want blurred, determine the blurring you want for that object, then apply a 2D blur before compositing other objects into the scene.
This is a cheat because in principle, different parts of the object may need different degrees of (depth of field) blurring. But it's not the only cheat in 3D graphics.
That said, there are other approaches. Ray-tracing can give true depth-of-field effects (if you're willing to pay the render-time costs). It's also possible to apply a blur to a 3D "voxel" grid instead of a 2D pixel grid - though I imagine that's more useful for smoothing shapes from e.g. medical scanners than for giving depth-of-field effects.
Blur is 2D operation, try to render object into texture and blur that texture.