Java 像素艺术的抗混叠算法

Java 像素艺术的抗混叠算法,java,algorithm,pixel,antialiasing,downsampling,Java,Algorithm,Pixel,Antialiasing,Downsampling,我有一个非常小的图像,或者说是像素艺术,因为没有更好的文字。它实际上只是一个大约这个大小的数字数组:newint[150][10]。我在这个阵列上画线和曲线,大部分是黑色背景上的一种颜色。这是为了控制一个LED带以后。所以现在我正在寻找一种方法来消除我画的线、曲线和形状的锯齿。我只想输入我的数组,有点像这样: int[]antialas(int[]image){ int[][]结果=新的int[image.length][image[0.length]; //在这里变魔术 返回结果; } 我偶

我有一个非常小的图像,或者说是像素艺术,因为没有更好的文字。它实际上只是一个大约这个大小的数字数组:
newint[150][10]
。我在这个阵列上画线和曲线,大部分是黑色背景上的一种颜色。这是为了控制一个LED带以后。所以现在我正在寻找一种方法来消除我画的线、曲线和形状的锯齿。我只想输入我的数组,有点像这样:

int[]antialas(int[]image){
int[][]结果=新的int[image.length][image[0.length];
//在这里变魔术
返回结果;
}
我偶然发现了吴的抗锯齿技术,但据我所知,它只用于绘制线条。如果有人能给我一个提示,告诉我应该寻找什么样的算法,我将不胜感激

我还了解到,通过下采样可以实现抗锯齿效果。对于我来说,以更高的分辨率创建阵列中的直线和曲线没有问题,因此这也是一个选项。但是我不知道如何执行下采样,我在互联网上找到的关于它的所有东西都与
Image
-对象一起工作,并使用库,这当然是没有选择的,因为我没有使用实际的图像。 我想要一个如下的下采样功能:

//比例应该是2的幂(我猜是??)
int[][]下采样(int[][]图像,int比例){
int[][]结果=新建int[image.length/2][image[0].length/2];
//在这里变魔术
如果(刻度>2)返回下采样(结果,刻度/2);
返回结果;
}

同样,如果有人对我可以研究哪种算法有好的想法,我将非常感激。

我研究了双线性插值,正如评论中所建议的那样。这就是我想到的。当结果维度正好是原始维度的一半时,该算法仅适用于缩小尺度。因为在缩小尺寸的过程中会丢失很多亮度,所以我会再次使所有像素变亮。仍然需要一个更好的解决方案,但它现在可以工作

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;
}
int[][]双线性缩小(int[][]原始,int比例,布尔加亮){
int[][]结果=新int[original.length/2][original[0].length/2];
//我们从中导出缩小像素的四个像素
//i=0->红色,i=1->绿色,i=2->蓝色
int a[]=新int[3];
int b[]=新int[3];
int c[]=新int[3];
int d[]=新int[3];
对于(int x=0;x>16&0xFF;
b[0]=(原始[x*2+1][y*2])>>16&0xFF;
c[0]=(原[x*2][y*2+1])>>16&0xFF;
d[0]=(原[x*2+1][y*2+1])>>16&0xFF;
a[1]=(原件[x*2][y*2])>>8&0xFF;
b[1]=(原始[x*2+1][y*2])>>8&0xFF;
c[1]=(原[x*2][y*2+1])>>8&0xFF;
d[1]=(原[x*2+1][y*2+1])>>8&0xFF;
a[2]=原件[x*2][y*2]&0xFF;
b[2]=原件[x*2+1][y*2]&0xFF;
c[2]=原件[x*2][y*2+1]&0xFF;
d[2]=原件[x*2+1][y*2+1]&0xFF;
//获取单独插值的颜色值
红色整数=(整数)(0.25*(a[0]+b[0]+c[0]+d[0]);
绿色整数=(整数)(0.25*(a[1]+b[1]+c[1]+d[1]);
蓝色整数=(整数)(0.25*(a[2]+b[2]+c[2]+d[2]);
//如果需要,应用饱和度
如果(变亮){
float hsb[]=Color.RGBtoHSB(红、绿、蓝、空);
hsb[2]=-((hsb[2]-1)*(hsb[2]-1))+1;
//计算新的颜色值
结果[x][y]=Color.hsb组织(hsb[0],hsb[1],hsb[2]);
}否则{
//计算新的颜色值

结果[x][y]=(红色我感觉您根本不需要抗锯齿。相反,您需要缩放/调整大小(这就是向上/向下采样)在已经光栅化的图像上使用双线性和双立方插值等方法。你也可以向上采样模糊一点,向下采样恢复一点,以使内容平滑一点…任何样本输入和想要的输出?嗯,缩放是一种选择,但反走样最终也是一种选择。目前我创建的阵列的大小我想以后再显示它。我可以我可以创建一个大得多的数组,然后缩小它的比例。但是反走样对我来说似乎更简单。输入是一个带有颜色(十六进制数)的二维整数数组:
int[][]lights=new int[150][10];
类似的东西。只有通过矢量图形(光栅化)渲染你的东西,反走样才有可能所以像素艺术在WU和类似的算法中是不可能的…因为像素艺术意味着光栅图像(不是矢量)这就是为什么缩放是一种方式啊,好吧。我想这是有道理的。你可以推荐任何好的资源让我看看缩放算法吗?只需谷歌双线性和双立方过滤或插值它真的很简单,网络上有很多关于它的东西。这不是双线性过滤,而是平均值…你应该这样做3次线性插值,所以如果你在浮动的
(x,y)
位置周围有
c0,c1,c2,c3
颜色,它就像
t=x-floor(x);c0=c0+(c1-c0)*t;c1=c2+(c3-c2)*t;t=y-floor(y);c0=c0+(c1-c0)*t、 
其中,
c0
是最终颜色…它适用于放大和缩小…请参阅并查找
//双线性插值A[fx][fy]->B[x][y]
在codeWell中,我从这里得到了算法:因为我可以安全地假设我总是将图像缩小到2的精确幂,我可以安全地假设w=0.5和h=0.5(在我链接的算法中是w,h)。如果w和h=0.5,公式可以简化,直到它离开我为止