0

Why do the graphics generated by my dithering algorithm have many black spots

here is picture

http://yanxuan.nosdn.127.net/00a07a53ab2083685da1a90d09452f69.png

Below is my code of Floyd Steinberg Dithering.

QImage * SaveThread::imageFloydSteinberg(QImage * origin)
{
    int old_pix, new_pix, quant_err;
    int width = origin->width();
    int height = origin->height();
    QImage * img_dither = new QImage(width, height, QImage::Format_ARGB32);
    img_dither = origin;
    for (int j = 0; j < height; j++)
    {
        for (int i = 0; i < width; i++)
        {
            old_pix = img_dither->pixel(i, j);
            if (img_dither->pixel(i, j) > qRgb(128, 128, 128))
                new_pix = qRgb(255, 255, 255);
            else
                new_pix = qRgb(0, 0, 0);

            img_dither->setPixel(i, j, qRgb(new_pix,new_pix,new_pix));

            quant_err = old_pix - new_pix;

            img_dither->setPixel(i+1, j  , img_dither->pixel(i+1, j  ) + quant_err * 7 / 16);
            img_dither->setPixel(i-1, j+1, img_dither->pixel(i-1, j+1) + quant_err * 3 / 16);
            img_dither->setPixel(i  , j+1, img_dither->pixel(i  , j+1) + quant_err * 5 / 16);
            img_dither->setPixel(i+1, j+1, img_dither->pixel(i+1, j+1) + quant_err * 1 / 16);
        }
    }
    return img_dither;
}
sorrowfeng
  • 17
  • 6
  • 1
    Firstly, you create a new `QImage` object pointed to by `img_dither` but then you immediately leak it and replace the pointer with `origin`. Perhaps you meant to _copy into_ it with `*img_dither = *origin;`? Secondly, you are addressing pixels outside the image's rectangle. I don't know how Qt handles this, but you should take care with pixels along the edges of an image so that you don't use illegal pixel addresses. – paddy Jul 29 '20 at 08:38
  • But the problem of black spots is not solved, what to do? – sorrowfeng Jul 29 '20 at 08:50
  • Honestly, I don't know if you're making any effort to debug this at all. If I look at `qRgb(new_pix,new_pix,new_pix)` it looks suspicious to me because `new_pix` is also created with `qRgb`. It's just plain wrong. This datatype is not useful for addition or subtraction, or even testing greater- or less-than. Operating on plain `int` will not affect individual color channels the way you think. You probably need to use `QColor`, but even that might not be the end of the story if `QColor` clamps (which ruins your multiplications). – paddy Jul 29 '20 at 09:17
  • I suggest you extract the pixel data and work out your individual color channel values with standard data types, then do addition/subtraction with `QColor`. Read this too: https://stackoverflow.com/questions/8892656/average-qrgb-values – paddy Jul 29 '20 at 09:18
  • Then `QImage` is not a `QObject`, you don't have to use it through pointers !! – Fareanor Jul 29 '20 at 09:19
  • ``` qRgb(new_pix,new_pix,new_pix)``` It was my carelessness. – sorrowfeng Jul 29 '20 at 09:35
  • the qRgb Equivalent to (int)AARRGGBB, I think there is nothing wrong in writing, I checked it many times – sorrowfeng Jul 29 '20 at 09:44

0 Answers0