Sign in to follow this  
Cookies

Error Diffusion dithering, too much contrast

Recommended Posts

Uhm, somewhere in November last year i decided to make a major update to Simulate Color Depth after being somewhere with lots of errors and crashes i got away from it and onto something else. A few days ago i decided to take it up again and decided just to write a whole new easier customizable error diffusion dithering class, success in nearly first try, and as planned i began to add XML support for custom dithers. On my way home from school today my computer had a bluescreen while it was sleeping, but luckily i had my project saved so it wasn't a big problem, so i came home turned on my computer, saw the bluescreen, restarted. Then i worked hard to get the XML stuff working but when i finally worked the result from the error diffusion had too much contrast based on how it was before i implented the XML support, that counts both for the same algorithm called from the data from the XML file and with the values i used before coded in directly, heres the class (default algorithm is Floyd-Steinberg, and the result is long away from what it have been, for a good guidance of how it should look like click here)

    internal class ErrorDiffusionSimple
   {
       const int ERROR = -190;
       int divisor;
       int[][] multiply;
       int boffset = ERROR;
       int foffset = ERROR;

       internal ErrorDiffusionSimple()
       {
           divisor = 16;
           multiply = new int[2][];
           multiply[0] = new int[1] { 7 };
           multiply[1] = new int[3] { 3, 5, 1 };
       }

       internal ErrorDiffusionSimple(int divisor, int[][] multiply)
       {
           this.divisor = divisor;
           this.multiply = multiply;
       }

       internal ErrorDiffusionSimple(int boffset, int foffset, int divisor, int[][] multiply)
       {
           this.boffset = boffset;
           this.foffset = foffset;
           this.divisor = divisor;
           this.multiply = multiply;
       }

       internal unsafe void ProcessDither(Surface src, Surface dst, PdnRegion reg, Rectangle rect, int BitDepth)
       {
           int sl = multiply[0].Length;
           int ll = multiply[1].Length;
           for (int y = rect.Top; y < rect.Bottom; y++)
           {
               for (int x = rect.Left; x < rect.Right; x++)
               {
                   ColorBgra cp = *(src.GetPointAddressUnchecked(x, y));
                   ColorBgra np = Dithering.GetClosestColor(cp, BitDepth);
                   for (int x2 = x+1; x2 <= x + sl; x2++)
                   {
                       if (reg.IsVisible(x2, y))
                           if (multiply[0][x2-1-x] != 0)
                               *(src.GetPointAddress(x2, y)) = errorDiffuse(cp, np, *(src.GetPointAddress(x2, y)), multiply[0][x2 - 1 - x]);
                   }
                   for (int y2 = y + 1; y2 < y + multiply.Length; y2++)
                   {
                      for (int x2 = x - (boffset == ERROR ? sl : boffset); x2 <= x + (foffset == ERROR ? sl : foffset); x2++)
                       {
                           if (reg.IsVisible(x2, y2))
                               if (multiply[y2 - y][x2 + (boffset == ERROR ? sl : boffset) - x] != 0)
                                   *(src.GetPointAddress(x2, y2)) = errorDiffuse(cp, np, *(src.GetPointAddress(x2, y2)), multiply[y2 - y][x2 + (boffset == ERROR ? sl : boffset) - x]);
                       }
                   }
                   *(dst.GetPointAddressUnchecked(x, y)) = np;
               }
           }
       }

       private ColorBgra errorDiffuse(ColorBgra c1, ColorBgra c2, ColorBgra c3, int multiplier)
       {
           int b, g, r;
           b = c1.B - c2.B;
           g = c1.G - c2.G;
           r = c1.R - c2.R;
           return ColorBgra.FromBgr(Clamp(c3.B + ((multiplier *  / divisor)), Clamp(c3.G + ((multiplier * g) / divisor)), Clamp(c3.R + ((multiplier * r) / divisor)));
       }

		private byte Clamp(int 
       {
			return Convert.ToByte(b < 0 ? 0 : b > 255 ? 255 : ;
       }
   }

Im now sure why it have changed contrast wise but it have (before the bluescreen, custom UI and XML stuff it worked fine and looked quite much, only with minor differences, like the picture i linked to above)

Edited by Cookies

Share this post


Link to post
Share on other sites

Just some extra info, it tried to copy the class into codelab and test with the default values (not anything loaded from anywhere) it worked fine, when i did the same in my solution it had too much contrast :/

edit:

Some comparisons

my result

badresult.png

how it should be more like

goodresult.png

edit2: Apparently i don't get the bad result if i run through the image in one run, so i dont know whats causing this :/ any ideas?

Edited by Cookies

Share this post


Link to post
Share on other sites

Well, as i said above i can only get the correct results if i process the whole image in one run, i tried quite a few things to get it working but for some reason it just dont want to come with the expected result if i dont run it through the whole image like

ErrorDiffusionSimple eds = new ErrorDiffusionSimple(divisor[DitherMethod], maps[DitherMethod]);
                       eds.ProcessDither(SrcClone, dstArgs.Surface, reg, srcArgs.Bounds, BitDepth);

which is extremely slow, and this problem only seem to be there with custom UI (only made a fast test from codelab, it ran fine there, and it ran fine before the custom UI) i have been thinking all day without coming closer to a solution, only made changes which change the ouput to even worse when clicking ok :/ and I always forget to make backups

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this