Pixels and image resizing
I came across this document about how pixels are not "little squares", and read it because I was under the impression that pixels were, in fact, little squares. I was wrong, and to summarize the document's point as I understand it: a pixel is more useful to us as a point sample of an image that exists independently of the resolution of the display. More on that in a second.
For me, the idea that pixels ARE little squares is an easy one to believe because of low-res video games where assets are visibly made up of little squares. Mario, for example, doesn't appear on the screen as a miniaturized (photographic) picture of a plumber, but is simply a relatively small number of squares of relatively few different colors arranged to sort of LOOK like a little plumber. The pixels are so big and each one constitutes such a large percentage of the entire image that they have to be considered blocks with which an image is made and not samples representative of a more complex image. If the size of Mario should increase (via zooming in, not via mushroom), then the pixels that form him should increase at the same rate, and not be blended or filtered in any way. Mario IS little square pixels and they should remain in tact.
Pixels in photographs, however, should be too small to consider individually, and should not increase in size as the size of the image increases. Instead the pixels should be spaced farther apart, and the resultant gaps should be filled with colors that would create a smooth transition from one sample to the next. This isn't a perfect solution, of course, and a higher resolution source will probably always look better than a low-res source upscaled to a higher-res, but the idea of resizing by treating the pixels as samples on a continuum of color values is far more useful visually than considering them picture elements which necessarily change in size along with the image. Here are two examples of a four pixel matrix made up of four different gray scale values. The one on the left is magnified about 20x and each pixel is 20x bigger as well. The one on the right is also magnified 20x, but each pixel was treated as a sample and spaced to the corners of the final image while all the rest of the pixels were filled in using values derived from the four samples.
The derivation is achieved by essentially drawing a circle around the sample, the edge of which abuts the next sample. The center of the circle is the sample color, and the edge of the circle is the closest sample's color, and everything in between is a percentage of both based on a cosine curve. Real image editing software uses a Gaussian filter which uses a more complicated formula, but the shape of the curve is similar to a cosine, so I went with the COS, modified a bit so that COS(0) = 1 and COS(180) = 0. Of course, not every derived pixel will be based on only two samples, and there's a large field in the center of the box that is an average of all four samples. The algorithm I came up with to find each value is:
FOR i = 0 TO 19
FOR j = 0 TO 19
Dist1 = SQR((j - 0) ^ 2 + (i - 0) ^ 2)
Dist2 = SQR((19 - j) ^ 2 + (i - 0) ^ 2)
Dist3 = SQR((j - 0) ^ 2 + (19 - i) ^ 2)
Dist4 = SQR((19 - j) ^ 2 + (19 - i) ^ 2)
IF Dist1 <= 18 THEN
CurPixel = CurPixel + Pixel(0) * (1 + COS((Dist1 * 10 * PI) / 180))
Total = Total + 1
END IF
IF Dist2 <= 18 THEN
CurPixel = CurPixel + Pixel(1) * (1 + COS((Dist2 * 10 * PI) / 180))
Total = Total + 1
END IF
IF Dist3 <= 18 THEN
CurPixel = CurPixel + Pixel(2) * (1 + COS((Dist3 * 10 * PI) / 180))
Total = Total + 1
END IF
IF Dist4 <= 18 THEN
CurPixel = CurPixel + Pixel(3) * (1 + COS((Dist4 * 10 * PI) / 180))
Total = Total + 1
END IF
IF Total > 0 THEN
PSET (50 + j, i), CurPixel / 2
END IF
CurPixel = 0
Total = 0
NEXT j
NEXT i
And looking it over again, it's a little bloated, but it works by counting from 0 to 19 twenty times to consider each of the pixels on the final 20x20 image. For each iteration of this loop, the four distances between the current pixel to the four samples (the corners) is found. Then, if the distance to a corner is less than or equal to 18 (the edge of the circle drawn around each sample), then the color of that corner is considered in the current pixel's value, and that color is defined as a percentage of the original color determined by the cosine of the distance from the corner multiplied by 10. That way at a distance of 0, the color will be 1*Original (COS(0*10)*Original), and at a distance of 18, the color will be 0*Original (COS(18*10)*Original). Each of the applicable colors is added together and divided by 2 (to be honest, I'm not exactly sure why 2. It doesn't represent an average since every value is divided by 2 even in the places where there are 4 samples, but I like how it looks) and then drawn in that position.
And maybe everyone already knows this, and maybe I'm not writing any of this in a way that makes any sense, but I thought it was interesting how image resizing works, and I thought I'd take a stab at making it work on a small scale and then try to show it to somebody.
Full code on comments.
