Your task is to implement a halftoning algorithm for a laser printer with a resolution of 1200dpi. You should use frequency modulation dithering ("FM dithering"), which uses random placement of equally sized dots on paper: darker areas of the image get more dots, while lighter ones get fewer.
Black dots are placed on the paper such that their density matches the brightness of the input image. Black (image value of 0) corresponds to the maximum density of dots in the printed area, so that the paper is completely covered by toner. White areas (image value 255) have no dots, so that completely white paper remains.
If one is placing dots for use on a high-quality laser printer, it is necessary to maintain a certain minimum distance between points (if they are not so densely spaced that they have to touch). For instance, you could use a version of Don Mitchell's algorithm'.
The result will be tested on a laser printer with a resolution of 1200dpi (eg. HP LaserJet 1320 or P2015), with dot sizes of 1x1 and 10x10.
The template application 068laser from the repository grcis serves as the basis of this project. This is an application which can load an image, and which automatically runs the method Dither.TransformImage() that calculates a transformed output image. You have to implement your technique in the file Dither.cs between the comment brackets:
// !!!{{ // !!!}}
The input image is passed to your method via the parameters Bitmap input, and fast data access can be used. Two numerical parameters indicate the desired output resolution. The output image is returned via the output parameter out Bitmap output. The user-specified text parameter string param is used to retrieve the following parameters in the demo application:
Reading the grey level of the input bitmap (including interpolation between neighbouring pixels) is done via the method Dither.GetGray(), but you have to use quick access to the fixed bitmap memory.
In case of Mitchell sampling you need quick searches for neighbouring pixels. To accelerate this, we recommend that you use some search data structure for 2D, such as e.g. grids, Point-quadtrees or KD-trese, which will be explained in the practical exercise.
Initialisation of parameters: in order to have all relevant code nicely grouped in a single location, you can initialise your application parameters in the function InitParams(). It is called during application start-up.
In the last parameter field out string name please write your full name (as well as in the comments on the first line of the source file). This will make it easier to perform automatic evaluations of the results.
As solution of the problem, you have to send us the file Dither.cs (and only that). If controlling your chosen algorithm uses any parameters, you have to properly document these in your submission mail.
Hand in the assignment until: 22. 12. 2016
Basic: 10 points for a functioning algorithm, plus a potential bonus of 1-5 points for efficiency and high quality output.
Visual Studio project: 068laser.
Modify and hand in the source file: Dither.cs
As a comment in the first line, please include your name!
You can use images from the repository data, and can also use frozentree.png, cate1600x1200bw.png or egsr1.png.
Copyright (C) 2016 J. Pelikán & A. Wilkie, last change: 2019-05-09 17:52:59 +0200 (Thu, 09 May 2019)