It is necessary to transfer the usual image to a format where shades of gray will be transmitted by the frequency of black dots.

enter image description here enter image description here

Points should be the same, round. At the output it is necessary to obtain a matrix of these points. Ideally, a color example would be, but would be dealt with first with BW.

Found information that it is called in print frequency-modulated rasterization. How can this algorithm be implemented? Where to look for information? I plan to write in Java.

  • For each point, calculate the average background in its neighborhood, and then convert it to a percentage. And I have a more interesting question: how then to draw it? - Qwertiy
  • Floyd-Steinberg dithering - MBo
  • So what is the task exactly? Do any dithering? Or do some very beautiful dithering? The usual line-by-line algorithm with the accumulation of errors will make you dithering, but it will not be so beautiful. - AnT
  • @AnT Yes, dithering is exactly what I need. Thanks, finally found out how it is properly called - Vlad Ogogo
  • This is called dithering, there are many lessons on the Internet. youtube.com/watch?v=0L2n8Tg2FwI - Vlad Ogogo

2 answers 2

For the view field

enter image description here

ordinary line-wise dithering with horizontal error transfer

int main() { const int S = 300; // Размер поля const int R = 256; // Диапазон яркостей for (int y = 0; y < S; ++y) { int error = 0; for (int x = 0; x < S; ++x) { int ideal = (x + y) * (R - 1) / (2 * (S - 1)); int corrected = ideal + error; int bw = corrected < R / 2 ? 0 : R - 1; error = corrected - bw; // Исходное поле: нарисовать точку (x, y) с яркостью `ideal` // Дизеринг: нарисовать точку (x, y) с яркостью `bw` } } } 

gives the following picture

enter image description here

(the pattern will depend on the size of the image). And if you need something more tricky - you decide.


Purely for fun:

The same, line by line, but with changing directions "back and forth" and with the global spread of the error

enter image description here

Simple unidirectional dithering along the diagonals from the lower left to the upper right.

enter image description here

Dithering around concentric squares, from the lower left corner counterclockwise, with global error propagation

enter image description here

The same, but with a random choice of the starting point on the square

enter image description here

Your initial version, however, was not obtained by such methods, but by a more cunning distribution of the error in neighboring points.

    This algorithm is not very difficult to implement:

    • Take the original image and bring it to the size you want to get in black and white points.
    • Set the rule according to which the points of the original type will turn into points of the new type. For example, if the old point was 75% of the maximum brightness, then the new is likely to be white will be 75%, and black - 25%.
    • convert each point of the original image to a new one.

       BufferedImage image1 = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); BufferedImage image2 = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { int gray = (i + j) + (( i + j) << 8) + ((i + j) << 16); image1.setRGB(i, j, gray); int bw = 0; if (Math.random() * 256 < (i+j)) bw = 0xFFFFFF; image2.setRGB(i, j, bw); } } JFrame window1 = new JFrame(); boolean flip = false; BufferedImage image; while (true) { if (flip) image = image1; else image = image2; window1.getContentPane().removeAll(); window1.setTitle("pic"); JLabel label = new JLabel(new ImageIcon(image)); window1.add(label); window1.setBounds(100, 100, 100, 200); window1.setVisible(true); Thread.sleep(500); flip = !flip; } 

      }

    In your example, there are three colors, so it looks somewhat better than pure conversion to b / w.