我有一个图像,或者说因缺乏更好的单词而缺少Pixelart,尺寸非常小。实际上,它只是一个大小约为new int[150][10]
的数字数组。我在此数组上绘制直线和曲线,大部分是在黑色背景上绘制一种颜色。这意味着稍后可以控制LED灯条。因此,现在我正在寻找一种对我绘制的直线,曲线和形状进行抗锯齿的方法。我只想输入我的数组,就像这样:
int[][] antiAlias(int[][] image) {
int[][] result = new int[image.length][image[0].length];
// do magic here
return result;
}
我偶然发现了Wu的抗锯齿,但据我所知,它仅用于绘制线条。如果有人能给我提示我应该寻找哪种算法,我将不胜感激。
我还读到,抗锯齿效果可以通过下采样来实现。因为对我来说,以更高的分辨率在阵列中创建直线和曲线不会有问题,所以这也可以是一种选择。但是我不知道如何执行降采样,而且我在互联网上可以找到的所有内容始终可以与Image
-对象和库一起使用,这当然是没有选择的,因为我没有使用实际的图片。
我想要一个这样的下采样功能:
// scale should be power of 2 (I guess??)
int[][] downsample(int[][] image, int scale) {
int[][] result = new int[image.length / 2][image[0].length / 2];
// do magic here
if (scale > 2) return downsample(result, scale / 2);
return result;
}
同样,如果有人对我有一个好主意,我可以研究哪种算法,我将非常感谢。
答案 0 :(得分:0)
正如注释中所建议的,我研究了双线性插值。这就是我想出的。仅当结果尺寸恰好是原始尺寸的一半时,该算法才适用于缩小比例。因为在缩小过程中会损失很多亮度,所以我再次使所有像素变亮。仍然需要一个更好的解决方案,但现在可以使用。
int[][] bilinearDownscale(int[][] original, int scale, boolean brighten) {
int[][] result = new int[original.length / 2][original[0].length / 2];
// the four pixels from which we derive our downscaled pixel
// i = 0 -> red, i = 1 -> green, i = 2 -> blue
int a[] = new int[3];
int b[] = new int[3];
int c[] = new int[3];
int d[] = new int[3];
for (int x = 0; x < result.length; x++) {
for (int y = 0; y < result[0].length; y++) {
// get the individual color values of the old pixels
a[0] = (original[x * 2][y * 2]) >> 16 & 0xFF;
b[0] = (original[x * 2 + 1][y * 2]) >> 16 & 0xFF;
c[0] = (original[x * 2][y * 2 + 1]) >> 16 & 0xFF;
d[0] = (original[x * 2 + 1][y * 2 + 1]) >> 16 & 0xFF;
a[1] = (original[x * 2][y * 2]) >> 8 & 0xFF;
b[1] = (original[x * 2 + 1][y * 2]) >> 8 & 0xFF;
c[1] = (original[x * 2][y * 2 + 1]) >> 8 & 0xFF;
d[1] = (original[x * 2 + 1][y * 2 + 1]) >> 8 & 0xFF;
a[2] = original[x * 2][y * 2] & 0xFF;
b[2] = original[x * 2 + 1][y * 2] & 0xFF;
c[2] = original[x * 2][y * 2 + 1] & 0xFF;
d[2] = original[x * 2 + 1][y * 2 + 1] & 0xFF;
// get the individually interpolated color values
int red = (int) (0.25 * (a[0] + b[0] + c[0] + d[0]));
int green = (int) (0.25 * (a[1] + b[1] + c[1] + d[1]));
int blue = (int) (0.25 * (a[2] + b[2] + c[2] + d[2]));
// apply saturation if so desired
if (brighten) {
float hsb[] = Color.RGBtoHSB(red, green, blue, null);
hsb[2] = -((hsb[2] - 1) * (hsb[2] - 1)) + 1;
// compute the new color value
result[x][y] = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
} else {
// compute the new color value
result[x][y] = (red << 16) | (green << 8) | blue;
}
}
}
// yay recursion
if (scale > 2) {
return bilinearDownscale(result, scale / 2, brighten);
}
return result;
}