How can I smooth output polylines?

It looks like you are allocating a rather small image:

image.allocate(300, 280);

If you need bitmap images, would it be possible to allocate a larger image, and draw the strokes larger too? For instance:

image.allocate(300*3, 280*3);

then use

ofScale(3, 3, 3);

before drawing the stroke to make it 3 times larger.

If you don’t need bitmap images you can indeed export vector files like SVG, PDF, DXF or something else. It depends on what you want to do with the output.

Hey thanks for the reponse. I think I know what my problem is…so allocating it does change the image so that its scaled on a larger canvas, but it still looks pixelated when zoomed in. Im running another program that needs to segment these lines (like cut em out) but it cant segment them because its made up of all these tiny blocks instead of a smooth line. Same thing again:
Is there a way to export it as a svg or pdf instead of png?

Are those blocks maybe just zoomed-in pixels?

With this code I can create an SVG with a circle and a curved line:

ofPolyline p;
for(int i=0; i<20; i++) {
    p.addVertex(i * 20, 50 + 50 * ofNoise(i * 0.1f));
ofDrawCircle(50, 50, 50);

Yeah…the segmenting program I have goes around per pixel though like a contour, so the lines would need to be thicker than 1 pixel. Like with: it does manage to get that long line at the top. But everything else is not connected. I think at least with a svg the lines would be cut out nicely if they were smooth (and would honestly just look better graphically).
Can I use ofBeginSaveScreenAsSVG in my case as a replacement?

As I understand it, your lines are originally based on vectors (they are polylines). Polylines are resolution independent and can be scaled up as much as you want without loosing detail. If you convert them to a bitmap (ofPixels, PNG, JPG), the vector data is lost and the lines become resolution dependent. If you scale up a pixel based image it becomes pixelated.

Maybe you could explain what you are trying to achieve with these images?

Not sure if it’s silly to share this link, but just in case: Understanding Vector and Bitmap Images.

Oh I see…is there a way then to just export the polylines directly to svgs? If that is done, will the drawings still look blocky or will they be like the image on the left: ?
Other than that, maybe if there were a way to increase the polyline thickness/thickness of the drawing that might be an easier way to resolve my problem.
Basically im breaking down the drawings into smaller lines, but then segmenting them for later use in another program: Help with script

Yes, you can export the polyline to svg.

Assuming you have a polyline called stroke:

// create a test polyline
ofPolyline stroke;
for(int i=0; i<20; i++) {
    float x = 20 + i * 20;
    float y = 50 + 50 * ofNoise(i * 0.1f);
    stroke.addVertex(x, y);

You can save it like this:

ofSetLineWidth(10); // control the thickness
// Note that the line won't be visible on the screen.
// If you want to see it also in your program, draw it
// again outside ofBegin../ofEndSaveScreenAsSVG()

It should look like the image on the left. You can open the resulting svg in your web browser and zoom in (CTRL+), or in Inkscape, Illustrator, etc.


Oh well thats good news!
So do I replace
ofSaveImage(pix, ofToDataPath("output/" + foldername + "/" + ofToString(_counter) + ".png"));
ofBeginSaveScreenAsSVG ?
Sorry…im a bit lost here

You have two version of addImage and I’m not sure which one you’re using.

I assume it would be something like:

void ncQuickDrawImageSave::addImage(ofPolyline & stroke, int _counter) {
  ofBeginSaveScreenAsSVG(ofToDataPath("output/" + foldername + "/" + ofToString(_counter) + ".svg"));

The one that accepts a vector as argument maybe should iterate over the vector and save each polyline as a separate file?

Ok, I realized that all I actually need is:
ofSetLineWidth(10); in order for my segmentation program to recognize the lines.
They just needed to be a bit thicker so that they could be contoured properly, nevermind outputting it as an svg.
However what im wondering now is, can the lines be smoothed without the need to export it as a svg?
Is there a way of rendering it more graphically pleasing like the idea they show in the second picture of: ?

Basically: can I still export as png, but correct the lines to make them smooth?

Take a look at this post. Maybe you can do something like this before drawing your stroke:

stroke= stroke.getResampledBySpacing(1);
stroke= stroke.getSmoothed(3);

Or try this one: ofxPoly

Hey hey, so you mean line 30?
I tried and it didnt do anything unfortunately…unless its supposed to be line 15, but I get a bunch of errors.
With this ofxPoly, how do I work it?? Do I do something like
void ofxPolyToMesh(ofMesh & mesh, const ofPolyline & polySource, float normalLength);
Smoother, better lines from ofPolyLine?

I think there’s a bit of confusion with the terms :slight_smile: smoothing can mean different things.

What getResampledBySpacing and getSmoothed would solve is a low amount of vertices in the polyline. So if your polyline looked like a Z with only 4 vertices, by resampling and smoothing you could make it look more like an flipped S with many more vertices.

On the other hand, the rendering engine does not produce beautiful lines when the thickness of lines is set very high. They look broken on sharp curves.
ugly sharp curves on polylines
For that issue you can use ofxPoly, which converts a line into a mesh. ofxPolyToMesh is different to other functions, in that it does not return the result, but it puts the result into its first argument. So you would call it like this:

ofMesh resultMesh;
ofxPolyToMesh(resultMesh, stroke, 10); // 10 pixel thickness
// now draw resultMesh (which is no longer a polyline, but a mesh!)
1 Like

this code produces this result:

    ofScale(3, 3, 3);

As @hamoid said before, to avoid those artifacts we can use ofxPoly. You need to download this addon and add it to your project using project generator. Add #include "ofxPoly.h" to ncQuickDrawImageSave.h. This code produces this:

    ofScale(3, 3, 3);
	ofMesh resultMesh;
	ofxPolyToMesh(resultMesh, stroke, 1);

It’s better but I think you want to achieve this? Am I right?

I tried to combine getResampledBySpacing() and getSmoothed() and ofxPoly but no success yet. Maybe someone else can help.

@SebastianSobotka Yeah thats right. Thanks for the help so far guys…ill look around as well and see if I can find anything else that can smooth those corners a bit better

Just wanted to double check…what about: ofxShivaVG (Smooth 2d graphics in oF)
Its a renderer, but it supports 2d polylines…

// .h
ofPolyline rough;
ofMesh smooth;

void ofApp::setup(){
    // create random test polyline
    for(int i=0; i<20; i++) {
        float x = 20 + i * 19;
        float y = 150 + 200 * ofNoise(i * 0.3f);
        rough.addVertex(x, y);
    // add extra points to polyline
    rough = rough.getResampledBySpacing(2);
    // smooth it (make it more rounded)
    rough = rough.getSmoothed(4);
    // make it thick with ofxPoly to avoid "glitchy corners"
    ofxPolyToMesh(smooth, rough, 4);
void ofApp::draw(){


    ofTranslate(0, 100);


Thanks, It’s a nice example. I had the same idea but had to play a little bit more with parameters.

	ofClear(255, 255, 255, 255);
	ofSetColor(0, 0, 0, 255);

	ofScale(3, 3, 3);

	// add extra points to polyline
	stroke = stroke.getResampledBySpacing(2);
	// smooth it (make it more rounded)
	stroke = stroke.getSmoothed(15);

	ofMesh resultMesh;
	ofxPolyToMesh(resultMesh, stroke, 2);


This is a combination of parameters getResampledBySpacing() and getSmoothed():

Looks pretty good. Still a little rough on the edges, but better than before for sure. Another thing from github:
Maybe this could help too? No idea