Comments (7)
Here is a simple example that renders a squirrel with a frame around it
use rasterize::*;
use std::{fs::File, io::BufWriter, sync::Arc};
type Error = Box<dyn std::error::Error>;
fn main() -> Result<(), Error> {
// Create path using builder
let squirrel_path: Arc<Path> = Path::builder()
.move_to((12.0, 1.0))
.cubic_to((9.79, 1.0), (8.0, 2.31), (8.0, 3.92))
.cubic_to((8.0, 5.86), (8.5, 6.95), (8.0, 10.0))
.cubic_to((8.0, 5.5), (5.23, 3.66), (4.0, 3.66))
.cubic_to((4.05, 3.16), (3.52, 3.0), (3.52, 3.0))
.cubic_to((3.52, 3.0), (3.3, 3.11), (3.22, 3.34))
.cubic_to((2.95, 3.03), (2.66, 3.07), (2.66, 3.07))
.line_to((2.53, 3.65))
.cubic_to((2.53, 3.65), (0.7, 4.29), (0.68, 6.87))
.cubic_to((0.88, 7.2), (2.21, 7.47), (3.15, 7.3))
.cubic_to((4.04, 7.35), (3.82, 8.09), (3.62, 8.29))
.cubic_to((2.78, 9.13), (2.0, 8.0), (1.0, 8.0))
.cubic_to((0.0, 8.0), (0.0, 9.0), (1.0, 9.0))
.cubic_to((2.0, 9.0), (2.0, 10.0), (4.0, 10.0))
.cubic_to((0.91, 11.2), (4.0, 14.0), (4.0, 14.0))
.line_to((3.0, 14.0))
.cubic_to((2.0, 14.0), (2.0, 15.0), (2.0, 15.0))
.line_to((8.0, 15.0))
.cubic_to((11.0, 15.0), (13.0, 14.0), (13.0, 11.53))
.cubic_to((13.0, 10.68), (12.57, 9.74), (12.0, 9.0))
.cubic_to((10.89, 7.54), (12.23, 6.32), (13.0, 7.0))
.cubic_to((13.77, 7.68), (16.0, 8.0), (16.0, 5.0))
.cubic_to((16.0, 2.79), (14.21, 1.0), (12.0, 1.0))
.close()
.move_to((2.5, 6.0))
.cubic_to((2.22, 6.0), (2.0, 5.78), (2.0, 5.5))
.cubic_to((2.0, 5.22), (2.22, 5.0), (2.5, 5.0))
.cubic_to((2.78, 5.0), (3.0, 5.22), (3.0, 5.5))
.cubic_to((3.0, 5.78), (2.78, 6.0), (2.5, 6.0))
.close()
.build()
.into();
// Squirrels bounding box
let squirrel_bbox = squirrel_path
.bbox(Transform::identity())
.ok_or("Empty path")?;
// Construct squirrel scene stroke and fill
let squirrel_scene = Scene::group(vec![
Scene::fill(
squirrel_path.clone(),
Arc::new("#d65d0e".parse::<LinColor>()?),
FillRule::default(),
),
Scene::stroke(
squirrel_path,
Arc::new("#af3a03".parse::<LinColor>()?),
StrokeStyle {
width: 0.3,
line_join: LineJoin::default(),
line_cap: LineCap::Round,
},
),
])
// fit it into 200x200 box with 10 pixel margin
.transform(Transform::fit_bbox(
squirrel_bbox,
BBox::new((10.0, 10.0), (190.0, 190.0)),
Align::Mid,
));
// Construct frame around squirrel
let frame_scene = Scene::stroke(
Path::builder()
.move_to((5.0, 5.0))
.rbox((190.0, 190.0), (15.0, 15.0))
.build()
.into(),
Arc::new("#98971a".parse::<LinColor>()?),
StrokeStyle {
width: 2.0,
line_join: LineJoin::default(),
line_cap: LineCap::Round,
},
);
// Construct full scene
let scene =
Scene::group(vec![frame_scene, squirrel_scene]).transform(Transform::new_scale(2.0, 2.0));
// Render image
let image = scene.render(
&ActiveEdgeRasterizer::default(),
Transform::identity(),
Some(BBox::new((0.0, 0.0), (400.0, 400.0))),
Some("#fbf1c7".parse()?),
);
// Write file
//
// Image pixels can also be iterated with
// `for pixel in image.iter().map(Color::to_rgb) { ... }`
let mut output = BufWriter::new(File::create("squirrel.bmp")?);
image.write_bmp(&mut output)?;
Ok(())
}
And here is the result:
I will add this to examples. Please let me know if you have any more questions.
from rasterize.
What is a "scene"? Is it a filled shape / area?
from rasterize.
Path
is what can be filled (squirrel path is filled with orange color) or stroked (and also stroked with dark orange color) and represents shape. The easiest way to construct it is to use Path::builder() ... .build()
or parse from an existing SVG Path with "...".parse::<Path>()
. You can think of a scene as something that represents an image but it has not been rendered yet. You can group different scenes with Scene::group
it can also be transformed (scaled, translated, rotated etc) with Scene::transform
, it also supports clipping with Scene::clip
(restrict a scene as if it can only be drawn inside a particular path). You can also fill/stroke shape with a radial/linear gradient. In general the model of this crate is similar to the SVG model.
from rasterize.
You can think of a scene as something that represents an image but it has not been rendered yet.
So a scene is like a command buffer?
from rasterize.
Sort of but I would describe it as a tree of shapes with additional details required for rendering, that can be converted to something like command buffer, it is traversed in the depth first order when rendered.
from rasterize.
One thing to note Path
can represent more than one shape that all rendered at once. For example data/material-big.path
represents thousands of shapes that are represented as single path.
from rasterize.
OK, thank you! :)
from rasterize.
Related Issues (5)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rasterize.