13 Parallel image processing

 

This chapter covers

  • Working with generalized algebraic data types
  • Safely avoiding return-type polymorphism
  • Writing a generic algorithm for transforming image data
  • Improving performance using parallelism

In the last chapter, we built a parser for PNM files, a simple image format. While we have covered the possibility of reading these files, we have not yet created a way of transforming them and writing them back to the filesystem. That will change with this chapter.

We want to cover using Haskell’s type system to create a data type that can dynamically store data of various types without needing to use parametric polymorphism while still being able to retrieve type information on this data later on. Then, we define a validation for our parsed data as well as a generic way of mapping data of different types. Finally, we cover how to perform work in parallel and more than double our program’s performance by using one single line of code.

13.1 Providing type information to the caller

The last chapter was all about parsing images in the portable anymap format (PNM). Now that we have these images in our program, we should do something with them. Let’s process them! More specifically, we want to build a generic way of changing the pixels of our image programmatically. This will enable us to write different filters, like

  • Grayscale
  • Pixelation
  • Blur

13.1.1 Problems with return-type polymorphism

13.1.2 Generalized algebraic data types

13.1.3 The Vector type

13.1.4 Dynamic types with existential quantification

13.2 Validation of parsed data

13.3 A generic algorithm for image conversion

13.3.1 Image algorithm for conversion matrices

13.3.2 Exporting images as PNG

13.4 Using parallelism to transform data

13.4.1 Measuring time

13.4.2 How parallelism works

13.4.3 All about sparks image process HECs (Haskell execution contexts)

Summary