【发布时间】:2016-04-17 14:54:56
【问题描述】:
我正在开发一个简单的图像处理工具,它应该能够在给定图像上应用滤镜。我想知道如何使用 lambda 表达式和流以函数式方式解决这个问题。
我编写了一个方法,该方法将内核作为带有 argb 值的 ArrayList 返回,然后可以根据我要应用的过滤器对其进行进一步处理。例如,如果我想应用一个盒子过滤器,我必须将所有元素相加,然后除以元素的数量。但当然,我必须分别对所有 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;
但我不确定如何使用流编写它,或者在此处插入什么来拆分值并独立处理它们并将结果重新组合在一起。
IntStream.range(0, src.length).parallel().forEach(i ->
dst[i] = getKernelValues(3, src, i, width, height).stream()
.mapToInt(Integer::intValue)
.sum() / 9);
我在这里写的是完全错误的,因为它需要整个 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;
});
【问题讨论】:
-
您当前的代码有什么问题?
-
如上一段所述,getKernelValues() 返回一个 argb 整数值的 ArrayList。但当然你需要分别处理所有颜色通道。
-
目前还不清楚你期待什么样的输出。可以举个例子吗?
-
嗯,我仍然不确定如何更好地解释它。也许它有助于举例说明我从 getKernelValues() 获得的值。此示例适用于我图片中随机位置的 9x9 滤镜尺寸。 int: -8224126 /// hex: 0xff828282 int: -8092540 /// hex: 0xff848484 int: -8224126 /// hex: 0xff828282 int: -8224126 /// hex: 0xff828282 int: -8092540 ///44 hex: 0xff88 int: -8224126 /// hex: 0xff828282 int: -8224126 /// hex: 0xff828282 int: -8092540 /// hex: 0xff848484 int: -8224126 /// hex: 0xff828282 抱歉,这里接缝输入不起作用
标签: java lambda filter java-stream argb