I tried to smoothen a line via the super-sampling anti-aliasing technique by adding transparency to neighboring pixels. Here is the code in C
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <png.h>
#define WIDTH 512
#define HEIGHT 512
int main()
{
// Image buffer
unsigned char image[HEIGHT][WIDTH][4];
for (int i = 0; i < HEIGHT; i++)
{
for (int j = 0; j < WIDTH; j++)
{
image[i][j][0] = 255;
image[i][j][1] = 255;
image[i][j][2] = 255;
image[i][j][3] = 0;
}
}
// A sample curve
for (double x = -M_PI; x <= M_PI; x += M_PI / WIDTH)
{
int y = (int)(HEIGHT / 2 - sin(x) * cos(x) * HEIGHT / 2);
int i = (int)(x * WIDTH / (2 * M_PI) + WIDTH / 2);
// The anti-aliasing part
int sample = 2; // how far we are sampling
double max_distance = sqrt(sample * sample + sample * sample);
for (int ii = -sample; ii <= sample; ii++)
{
for (int jj = -sample; jj <= sample; jj++)
{
int iii = i + ii;
int jjj = y + jj;
if (iii >= 0 && iii < WIDTH && jjj >= 0 && jjj < HEIGHT)
{
// Here is my question
int alpha = 255 - (int)(100.0 * sqrt(ii * ii + jj * jj) / max_distance);
image[jjj][iii][0] = 0;
image[jjj][iii][1] = 0;
image[jjj][iii][2] = 0;
image[jjj][iii][3] = alpha > image[jjj][iii][3] ? alpha : image[jjj][iii][3];
}
}
}
}
FILE *fp = fopen("curve.png", "wb");
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info = png_create_info_struct(png);
png_init_io(png, fp);
png_set_IHDR(png, info, WIDTH, HEIGHT, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png, info);
for (int i = 0; i < HEIGHT; i++)
{
png_write_row(png, (png_bytep)image[i]);
}
png_write_end(png, NULL);
fclose(fp);
return 0;
}
Although it does some smoothing, but the result is far from the available programs. Where did I do wrong?
I tried to calculate the transparency based on the distance of each neighboring pixel from the center of the line:
int alpha = 255 - (int)(100.0 * sqrt(ii * ii + jj * jj) / max_distance);
I used the factor of 100 instead of 255 since we do not need to go deep into full transparency.
The problem is how to set the alpha value for each pixel based on neighboring pixels when the transparency of each neighbor is subject to change according to its neighbors?