1
$\begingroup$

I read the pixels of PNG files via libpng and creates an array of alpha channels (showing visible pixels for a monochromatic image).

int pixels[height][width];

for( int i=0; i<height; i++){
    for( int j=0; j<width; j++){
        if(pixels[i][j]>0){
            double x = (double)j;
            double y = (double)i;
        }
    }
}

This creates steps at curvatures. Anti-aliasing uses lighter pixels to visually create smoothness at the edges. Assuming the image has only black pixels, and the alpha channel is used for anti-aliasing only, I decided to move the points (x,y) according to the alpha value

for( int i=0; i<height; i++){
    for( int j=0; j<width; j++){
        if(pixels[i][j]>0){ // visible pixels
            double x = (double)j;
            double y = (double)i;

            if(pixels[i][j]<255){ // anti-aliasing partly transparent pixels
                if(pixels[i][j-1]==0){  // left edge
                x+=(double)(255-pixels[i][j])/255 // move the point to the right
            }
            else if(pixels[i][j]<255){ 
                if(pixels[i][j+1]==0){  // right edge
                x-=(double)(255-pixels[i][j])/255 // move the point to the left
            }
            // and the same for the vertical edges
        }
    }
}

This massively improved the edge smoothness, but I believe the logic I followed is totally wrong, as it cannot account for the curves. For example,

enter image description here

Programs like potrace do this job by transforming edges to paths, but here I just want to re-arrange the pixels points to form smooth edges (imagine we are creating the edges by dots instead of cubic pixels) rather than creating bezier curves.

What is the practical way to capture points at the edge of PNG pixels with smoothness?

$\endgroup$
2
  • 1
    $\begingroup$ It's a little hard to understand what kind of output you want this algorithm to have. I don't quite see what you're doing with the "move the point to the left or right" business. Maybe you could create a mock-up diagram showing what you would like the output to look like for the antialiased curve image you posted? Also, you might look into the Marching Squares algorithm, as it sounds related to what you're doing. $\endgroup$ Commented Feb 24, 2022 at 19:20
  • $\begingroup$ @NathanReed I just want to restore the edge through a series of points. Each pixel gives the coordinates of its bottom-left corner. If we draw a circle for each pixel, we will have stairs-stepping. To have a smooth line, we have to move the points according to the anti-aliasing. I asked a follow-up question after some modification stackoverflow.com/questions/71251060/… it can better clarify the case. $\endgroup$
    – Googlebot
    Commented Feb 24, 2022 at 19:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.