Java流-处理rgb值

Java流-处理rgb值,java,lambda,filter,java-stream,argb,Java,Lambda,Filter,Java Stream,Argb,我正在开发一个简单的图像处理工具,应该能够对给定的图像应用过滤器。我想知道如何用lambda表达式和流以函数的方式解决这个问题 我编写了一个方法,该方法将内核作为ArrayList返回,并带有argb值,然后可以根据我要应用的过滤器对其进行进一步处理。例如,如果我想应用一个长方体过滤器,我必须将所有元素相加,然后除以元素数。当然,我必须分别对所有rgb值进行处理 我以前得到的值如下所示: // Get rgb values: r = (argb >> 16) &

我正在开发一个简单的图像处理工具,应该能够对给定的图像应用过滤器。我想知道如何用lambda表达式和流以函数的方式解决这个问题

我编写了一个方法,该方法将内核作为ArrayList返回,并带有argb值,然后可以根据我要应用的过滤器对其进行进一步处理。例如,如果我想应用一个长方体过滤器,我必须将所有元素相加,然后除以元素数。当然,我必须分别对所有rgb值进行处理

我以前得到的值如下所示:

// Get rgb values:  
    r = (argb >> 16) & 0xff;  
    g = (argb >> 8) & 0xff;  
    b = argb & 0xff;  
// Write back to argb:  
    argb = (0xFF << 24) | (r << 16) | (g << 8) | b;
我在这里写的是完全错误的,因为它需要整个argb值。但也许你们可以帮我把这个图片改成一个工作示例,我可以在以后用于其他过滤器

提前谢谢

编辑:
同时,我通过如下拆分值绕过了这个问题。这是可行的,但仍然有重复的代码。如果有人知道如何在更少的代码,我很乐意知道

无论如何,谢谢你

IntStream.range(0, src.length).parallel().forEach(i -> {
    ArrayList<Integer> values = getKernelValues(filterSize, src, i, width, height);
        int r = values
            .stream()
            .map(j -> (j >> 16) & 0xff)
            .reduce(0, (j, k) -> j + k);
        r /= (filterSize * filterSize);

        int g = values
            .stream()
            .map(j -> (j >> 8) & 0xff)
            .reduce(0, (j, k) -> j + k);
        g /= (filterSize * filterSize);

        int b = values
            .stream()
            .map(j -> j & 0xff)
            .reduce(0, (j, k) -> j + k);
        b /= (filterSize * filterSize);

        dst[i] = 0xff << 24 | r << 16 | g << 8 | b;
});
IntStream.range(0,src.length).parallel().forEach(i->{
ArrayList值=GetKernelValue(filterSize、src、i、宽度、高度);
int r=值
.stream()
.map(j->(j>>16)和0xff)
.减少(0,(j,k)->j+k);
r/=(filterSize*filterSize);
int g=值
.stream()
.map(j->(j>>8)和0xff)
.减少(0,(j,k)->j+k);
g/=(filterSize*filterSize);
int b=值
.stream()
.map(j->j&0xff)
.减少(0,(j,k)->j+k);
b/=(filterSize*filterSize);

dst[i]=0xff我觉得你需要平均所有的r值、g值和b值。如果我是正确的,首先要注意的是,你不能在int的8位空间内对每个值求和,因为在你将结果除以值的数量之前,总和将超过8位。所以你需要做的第一件事是提取r、g、a将b值转换为单独的整数值以保存总和。您可以创建带有整数字段的RGB类,但整数数组可以:

static int[] unpackARGB(int argb){
    return new int[] { (argb >> 16) & 0xff, (argb >> 8) & 0xff, argb & 0xff };
}

static int packARGB(int[] ints){
    return (0xff << 24 + ints[0] & 0xff) << 16 + (ints[1] & 0xff) << 8 + ints[2] & 0xff;
}
稍后,我们需要将每个值除以,使其回到其8位范围,因此这种方便的方法将有助于:

static int[] divRGB(int[] arr1, int divisor){
    return new int[] { arr1[0]/divisor, arr1[1]/divisor, arr1[2]/divisor };
}
然后,我们可以创建一个函数来执行平均操作:

public static int averageRGB(IntStream ints, int size) {
    int[] sum = ints
            .parallel()
            .mapToObj(i -> unpackARGB(i))
            .reduce(new int[]{0,0,0}, (a, v) -> sumRGB(a, v));
    return packARGB(divRGB(sum, size));
} 
从列表中,您可以这样调用它:

int result = averageRGB(integerList.stream().mapToInt(i->i), integerList.size());

您当前的代码有什么问题?如上一段getKernelValues()中所述返回argb整数值的ArrayList。但当然,您需要单独处理所有颜色通道。仍然不清楚您期望的输出类型。您可以发布一个示例吗?嗯,仍然不确定如何更好地解释它。也许可以举一个示例,说明我从getKernelValues()获得的值。此示例适用于图片中任意位置的9x9筛选器大小。int:-8224126///hex:0xff828282 int:-8092540///hex:0xff848484 int:-8224126///hex:0xff828282 int:-8224126///hex:0xff828282 int:-8092540///hex:0xFF8484 int:-8224126///hex:0xFF8282 int:-8224126///hex:0xff828282 int:-8092540///hex:0xff848484 int:-8224126///hex:0xff828282抱歉,它在这里不起作用
public static int averageRGB(IntStream ints, int size) {
    int[] sum = ints
            .parallel()
            .mapToObj(i -> unpackARGB(i))
            .reduce(new int[]{0,0,0}, (a, v) -> sumRGB(a, v));
    return packARGB(divRGB(sum, size));
} 
int result = averageRGB(integerList.stream().mapToInt(i->i), integerList.size());