java - Pixelart 的抗锯齿算法
问题描述
我有一个图像,或者 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;
}
同样,如果有人对我可以研究什么样的算法有一个好主意,我将非常感激。
解决方案
正如评论中所建议的那样,我查看了双线性插值。这就是我想出的。该算法仅适用于当结果尺寸恰好是原始尺寸的一半时的缩小。因为在缩小过程中会丢失很多亮度,所以我再次将所有像素变亮。仍然需要一个更好的解决方案,但它现在有效。
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;
}
推荐阅读
- tensorflow - ValueError:获取参数
不能解释为张量 - php - 在 laravel/PHP 中具有相同命名空间的 2 个类
- java - 当我第二次尝试运行 Hello Agent 时,会发生此错误
- wordpress - Google App Engine Docker 容器 502 错误网关
- python - 立方体的投影面积计算
- reactjs - react-scripts:在反应应用程序中找不到命令
- r - 如何为这个场景制作一个好的情节
- python - Python嵌套的defaultdict问题
- java - 循环遍历数组的各个部分
- java - 选择要用于身份验证的特定指纹