功能上穿越图像的习惯方式 [英] Idiomatic Way of Traversing Image, Functionally

查看:119
本文介绍了功能上穿越图像的习惯方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Java 8并试图编写纯粹的功能代码。在我最近的一个项目中,我需要遍历图像中的每个像素,并对每个像素执行一些计算。我想出的代码如下所示:

  IntStream 
.range(0,newImage.getWidth() )
.forEach(i - > IntStream
.range(0,newImage.getHeight())
.forEach(n - > {
inspectPixel(i,n, newImage);
})
);

然而,命令式版本就像这样:

  for(int i = 0; i  for(int n = 0; n  inspectPixel(i,n,newImage); 


$ / code $ / pre

也许这只是因为我太习惯命令式编程,但后者似乎比前者更具可读性。其中一件事正在发生:


  1. 我的代码错了,我是否以错误的方式回答了这个问题?如果是这样,代码应该是什么样的?你如何在功能上遍历任何二维数据结构,而不仅仅是一个图像?

  2. 这实际上是程序的最佳版本,它对于Java 8来说是功能性的,这种情况很简单用于函数式编程。


解决方案

这是因为 IntStream 没有专门针对迭代像素。详细程度是对流的力量的牺牲。虽然功能,但它的目的不符合您的需求。



您可以创建自己的界面来处理混乱的工作:

  class PixelScanner {
public static void scan(BufferedImage image,PixelInspector inspector){
int [] pixels =((DataBufferInt)image.getRaster() 。.getDataBuffer())的getData();
for(int y = 0; y for(int x = 0; x int pixel = pixels [x + y * image.getWidth()];
inspector.inspect(pixel);
}
}
}
}

interface PixelInspector {
void inspect(int pixel);
}

然后您可以使用它:

  PixelScanner.scan(图像,像素 - > {
//检查像素
});

甚至可以添加更多参数进行检查,例如像素位于哪个(x,y)位置。你甚至可以包装每个像素以将更多的数据传递给检查员。我还建议使用 scan 非静态,并使用 PixelScanner 对象代替。函数式编程是有用的,但OOP肯定有它的焦点时刻,并且都应该被有效地使用。


I'm using Java 8 and trying to write pure functional code. In my latest project, I need to step through every pixel in an image and perform some computation on every pixel. The code I came up with goes something like this:

IntStream
        .range(0, newImage.getWidth())
        .forEach(i -> IntStream
                .range(0, newImage.getHeight())
                .forEach(n -> {
                    inspectPixel(i, n, newImage);
                })
        );

However, the imperative version goes something like this:

for (int i = 0; i < newImage.getWidth(); i++){
    for (int n = 0; n < newImage.getHeight(); n++){
        inspectPixel(i, n, newImage);
    }
}

Maybe this is just because I'm too used to imperative programming, but the latter seems more readable than the former. One of two things is going on:

  1. My code is wrong, am I going about this the wrong way? If so, what should the code look like? How do you functionally traverse any two dimensional data structure, not just an image?
  2. This actually is the best version of the program in a functional way for Java 8, and this situation is simply poor for functional programming.

解决方案

That's because IntStream was not specifically targeted towards iterating over pixels. The verbosity is a sacrifice for the power of the stream. Although functional, it's purpose does not fit your needs.

You could always create your own interface to handle the messy work:

class PixelScanner {
    public static void scan(BufferedImage image, PixelInspector inspector) {
        int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        for(int y = 0; y < image.getHeight(); y++) {
            for(int x = 0; x < image.getWidth(); x++) {
                int pixel = pixels[x + y * image.getWidth()];
                inspector.inspect(pixel);
            }
        }
    }
}

interface PixelInspector {
    void inspect(int pixel);
}

Which you can then use as:

PixelScanner.scan(image, pixel -> {
    // inspect pixel
});

Could even add more parameters to inspect, such as which (x, y) position that pixel is in. You could even wrap each pixel to pass more data about it to the inspector. I also suggest making scan non-static and using a PixelScanner object instead. Functional programming is useful, but OOP definitely has it's spotlight moments, and both should be used effectively.

这篇关于功能上穿越图像的习惯方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆