Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

colors - c# image dithering routine that accepts an amount of dithering?

I've been using aforge's floyed-steinberg dithering method, but I noticed that you can't specify the amount of dithering. I'd like to be able to specify an amount between 0 and 100. So that if I ask for 50, it will dither half as much as 100. Or, if I specify 0, then the resulting image will be made of solid colors with hard edges between each color... or in other words, no dithering. I'm looking for c# code for a routine such as floyed-steinberg, or Jarvis, Judice, Ninke dithering, that accepts an amount. anyone know of any?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

with slight change of this dithering you can achieve the dithering scalability. Just scale the color accumulator (leftovers) r0,g0,b0 by your scale <0,1>

Example (GIF) animation:

example

Here just the C++ dithering part (rest is in the link above)

// dithering
r0=0; g0=0; b0=0;   // no leftovers
for (y=0;y<pic0.ys;y++)
 for (x=0;x<pic0.xs;x++)
    {
    // get source pixel color
    c=pic0.p[y][x];
    // add to leftovers
    r0+=WORD(c.db[picture::_r]);
    g0+=WORD(c.db[picture::_g]);
    b0+=WORD(c.db[picture::_b]);
    // find closest color from pal[]
    for (i=0,j=-1;i<pal.num;i++)
        {
        c=pal[i];
        r=WORD(c.db[picture::_r]);
        g=WORD(c.db[picture::_g]);
        b=WORD(c.db[picture::_b]);
        e=(r-r0); e*=e; d =e;
        e=(g-g0); e*=e; d+=e;
        e=(b-b0); e*=e; d+=e;
        if ((j<0)||(d0>d)) { d0=d; j=i; }
        }
    // get selected palette color
    c=pal[j];
    // sub from leftovers
    r0-=WORD(c.db[picture::_r]);
    g0-=WORD(c.db[picture::_g]);
    b0-=WORD(c.db[picture::_b]);
    // scale dithering
    r0=(r0*coef)/100;
    g0=(g0*coef)/100;
    b0=(b0*coef)/100;
    // copy to destination image
    pic2.p[y][x]=c;
    }

Where coef = <0,100> is your scale. The only change from the code in linked answer is added 3 lines for scale dithering. Here examples with VGA 256 color default palette:

coef = 100

enter image description here

coef = ~75

enter image description here

coef = ~50

enter image description here

coef = ~25

enter image description here

coef = 0

enter image description here

[Notes]

My coef is set by a scroll bar so only the 0% and 100% are precise all other coefficients could be near selected value.

If you change the coefficient range to power of 2 for example <0,128> then you can use bitshifts instead of division while scaling.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...