Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / MFC

ImageStone - A Powerful C++ Class Library for Image Manipulation

Rate me:
Please Sign up or sign in to vote.
4.81/5 (250 votes)
6 Dec 2011Zlib3 min read 117.6K   51.5K   405  
An article on a library for image manipulation
//-------------------------------------------------------------------------------------
/// Lens flare (>=24 bit).
class FCEffectLensFlare : public FCImageEffect
{
public:
    /**
        Constructor \n
        pt - coordinate on image
    */
    FCEffectLensFlare (POINT pt) : m_pt(pt) {}
private:
    struct FLOATRGB
    {
        double  r ;
        double  g ;
        double  b ;
    };
    struct Reflect
    {
        FLOATRGB ccol ;
        double   size ;
        int      xp ;
        int      yp ;
        int      type ;
    };

    void initref (int sx, int sy, int width, int height, int matt)
    {
        int   xh = width / 2,
              yh = height / 2,
              dx = xh - sx,
              dy = yh - sy ;
        m_numref = 19 ;
        m_ref[0].type=1; m_ref[0].size=matt*0.027;
        m_ref[0].xp=(int)(0.6699*dx+xh); m_ref[0].yp=(int)(0.6699*dy+yh);
        m_ref[0].ccol.r=0.0; m_ref[0].ccol.g=14.0/255.0; m_ref[0].ccol.b=113.0/255.0;
        m_ref[1].type=1; m_ref[1].size=matt*0.01;
        m_ref[1].xp=(int)(0.2692*dx+xh); m_ref[1].yp=(int)(0.2692*dy+yh);
        m_ref[1].ccol.r=90.0/255.0; m_ref[1].ccol.g=181.0/255.0; m_ref[1].ccol.b=142.0/255.0;
        m_ref[2].type=1; m_ref[2].size=matt*0.005;
        m_ref[2].xp=(int)(-0.0112*dx+xh); m_ref[2].yp=(int)(-0.0112*dy+yh);
        m_ref[2].ccol.r=56.0/255.0; m_ref[2].ccol.g=140.0/255.0; m_ref[2].ccol.b=106.0/255.0;
        m_ref[3].type=2; m_ref[3].size=matt*0.031;
        m_ref[3].xp=(int)(0.6490*dx+xh); m_ref[3].yp=(int)(0.6490*dy+yh);
        m_ref[3].ccol.r=9.0/255.0; m_ref[3].ccol.g=29.0/255.0; m_ref[3].ccol.b=19.0/255.0;
        m_ref[4].type=2; m_ref[4].size=matt*0.015;
        m_ref[4].xp=(int)(0.4696*dx+xh); m_ref[4].yp=(int)(0.4696*dy+yh);
        m_ref[4].ccol.r=24.0/255.0; m_ref[4].ccol.g=14.0/255.0; m_ref[4].ccol.b=0.0;
        m_ref[5].type=2; m_ref[5].size=matt*0.037;
        m_ref[5].xp=(int)(0.4087*dx+xh); m_ref[5].yp=(int)(0.4087*dy+yh);
        m_ref[5].ccol.r=24.0/255.0; m_ref[5].ccol.g=14.0/255.0; m_ref[5].ccol.b=0.0;
        m_ref[6].type=2; m_ref[6].size=matt*0.022;
        m_ref[6].xp=(int)(-0.2003*dx+xh); m_ref[6].yp=(int)(-0.2003*dy+yh);
        m_ref[6].ccol.r=42.0/255.0; m_ref[6].ccol.g=19.0/255.0; m_ref[6].ccol.b=0.0;
        m_ref[7].type=2; m_ref[7].size=matt*0.025;
        m_ref[7].xp=(int)(-0.4103*dx+xh); m_ref[7].yp=(int)(-0.4103*dy+yh);
        m_ref[7].ccol.b=17.0/255.0; m_ref[7].ccol.g=9.0/255.0; m_ref[7].ccol.r=0.0;
        m_ref[8].type=2; m_ref[8].size=matt*0.058;
        m_ref[8].xp=(int)(-0.4503*dx+xh); m_ref[8].yp=(int)(-0.4503*dy+yh);
        m_ref[8].ccol.b=10.0/255.0; m_ref[8].ccol.g=4.0/255.0; m_ref[8].ccol.r=0.0;
        m_ref[9].type=2; m_ref[9].size=matt*0.017;
        m_ref[9].xp=(int)(-0.5112*dx+xh); m_ref[9].yp=(int)(-0.5112*dy+yh);
        m_ref[9].ccol.r=5.0/255.0; m_ref[9].ccol.g=5.0/255.0; m_ref[9].ccol.b=14.0/255.0;
        m_ref[10].type=2; m_ref[10].size=matt*0.2;
        m_ref[10].xp=(int)(-1.496*dx+xh); m_ref[10].yp=(int)(-1.496*dy+yh);
        m_ref[10].ccol.r=9.0/255.0; m_ref[10].ccol.g=4.0/255.0; m_ref[10].ccol.b=0.0;
        m_ref[11].type=2; m_ref[11].size=matt*0.5;
        m_ref[11].xp=(int)(-1.496*dx+xh); m_ref[11].yp=(int)(-1.496*dy+yh);
        m_ref[11].ccol.r=9.0/255.0; m_ref[11].ccol.g=4.0/255.0; m_ref[11].ccol.b=0.0;
        m_ref[12].type=3; m_ref[12].size=matt*0.075;
        m_ref[12].xp=(int)(0.4487*dx+xh); m_ref[12].yp=(int)(0.4487*dy+yh);
        m_ref[12].ccol.r=34.0/255.0; m_ref[12].ccol.g=19.0/255.0; m_ref[12].ccol.b=0.0;
        m_ref[13].type=3; m_ref[13].size=matt*0.1;
        m_ref[13].xp=(int)(dx+xh); m_ref[13].yp=(int)(dy+yh);
        m_ref[13].ccol.r=14.0/255.0; m_ref[13].ccol.g=26.0/255.0; m_ref[13].ccol.b=0.0;
        m_ref[14].type=3; m_ref[14].size=matt*0.039;
        m_ref[14].xp=(int)(-1.301*dx+xh); m_ref[14].yp=(int)(-1.301*dy+yh);
        m_ref[14].ccol.r=10.0/255.0; m_ref[14].ccol.g=25.0/255.0; m_ref[14].ccol.b=13.0/255.0;
        m_ref[15].type=4; m_ref[15].size=matt*0.19;
        m_ref[15].xp=(int)(1.309*dx+xh); m_ref[15].yp=(int)(1.309*dy+yh);
        m_ref[15].ccol.r=9.0/255.0; m_ref[15].ccol.g=0.0; m_ref[15].ccol.b=17.0/255.0;
        m_ref[16].type=4; m_ref[16].size=matt*0.195;
        m_ref[16].xp=(int)(1.309*dx+xh); m_ref[16].yp=(int)(1.309*dy+yh);
        m_ref[16].ccol.r=9.0/255.0; m_ref[16].ccol.g=16.0/255.0; m_ref[16].ccol.b=5.0/255.0;
        m_ref[17].type=4; m_ref[17].size=matt*0.20;
        m_ref[17].xp=(int)(1.309*dx+xh); m_ref[17].yp=(int)(1.309*dy+yh);
        m_ref[17].ccol.r=17.0/255.0; m_ref[17].ccol.g=4.0/255.0; m_ref[17].ccol.b=0.0;
        m_ref[18].type=4; m_ref[18].size=matt*0.038;
        m_ref[18].xp=(int)(-1.301*dx+xh); m_ref[18].yp=(int)(-1.301*dy+yh);
        m_ref[18].ccol.r=17.0/255.0; m_ref[18].ccol.g=4.0/255.0; m_ref[18].ccol.b=0.0;
    }

    static void fixpix (BYTE* p, double procent, const FLOATRGB& colpro)
    {
        PCL_R(p) = (BYTE)(PCL_R(p) + (255 - PCL_R(p)) * procent * colpro.r) ;
        PCL_G(p) = (BYTE)(PCL_G(p) + (255 - PCL_G(p)) * procent * colpro.g) ;
        PCL_B(p) = (BYTE)(PCL_B(p) + (255 - PCL_B(p)) * procent * colpro.b) ;
    }
    void mcolor (BYTE* s, double h)
    {
        double   procent = 1 - h/m_scolor ;
        if (procent > 0)
        {
            procent *= procent ;
            fixpix (s, procent, m_color) ;
        }
    }
    void mglow (BYTE* s, double h)
    {
        double   procent = 1 - h/m_sglow ;
        if (procent > 0)
        {
            procent *= procent ;
            fixpix (s, procent, m_glow) ;
        }
    }
    void minner (BYTE* s, double h)
    {
        double   procent = 1 - h/m_sinner ;
        if (procent > 0)
        {
            procent *= procent ;
            fixpix (s, procent, m_inner) ;
        }
    }
    void mouter (BYTE* s, double h)
    {
        double   procent = 1 - h/m_souter ;
        if (procent > 0)
            fixpix (s, procent, m_outer) ;
    }
    void mhalo (BYTE* s, double h)
    {
        double   procent = fabs((h - m_shalo) / (m_shalo * 0.07)) ;
        if (procent < 1)
            fixpix (s, 1 - procent, m_halo) ;
    }
    static void mrt1 (BYTE* s, Reflect* r, int x, int y)
    {
        double   procent = 1 - FHypot (r->xp - x, r->yp - y) / r->size ;
        if (procent > 0)
        {
            procent *= procent ;
            fixpix (s, procent, r->ccol) ;
        }
    }
    static void mrt2 (BYTE* s, Reflect* r, int x, int y)
    {
        double   procent = r->size - FHypot (r->xp - x, r->yp - y) ;
        procent /= (r->size * 0.15) ;
        if (procent > 0)
        {
            if (procent > 1)
                procent = 1 ;
            fixpix (s, procent, r->ccol) ;
        }
    }
    static void mrt3 (BYTE* s, Reflect* r, int x, int y)
    {
        double   procent = r->size - FHypot (r->xp - x, r->yp - y) ;
        procent /= (r->size * 0.12) ;
        if (procent > 0)
        {
            if (procent > 1)
                procent = 1 - (procent * 0.12) ;
            fixpix (s, procent, r->ccol) ;
        }
    }
    static void mrt4 (BYTE* s, Reflect* r, int x, int y)
    {
        double   procent  = FHypot (r->xp - x, r->yp - y) - r->size ;
        procent /= (r->size * 0.04) ;
        procent  = fabs (procent) ;
        if (procent < 1)
            fixpix (s, 1 - procent, r->ccol) ;
    }

    virtual void OnBeforeProcess (FCObjImage& img)
    {
        int   matt = img.Width() ;
        m_scolor = matt * 0.0375;
        m_sglow  = matt * 0.078125;
        m_sinner = matt * 0.1796875;
        m_souter = matt * 0.3359375;
        m_shalo  = matt * 0.084375;

        m_color.r = 239.0/255.0; m_color.g = 239.0/255.0; m_color.b = 239.0/255.0;
        m_glow.r  = 245.0/255.0; m_glow.g  = 245.0/255.0; m_glow.b  = 245.0/255.0;
        m_inner.r = 255.0/255.0; m_inner.g = 38.0/255.0;  m_inner.b = 43.0/255.0;
        m_outer.r = 69.0/255.0;  m_outer.g = 59.0/255.0;  m_outer.b = 64.0/255.0;
        m_halo.r  = 80.0/255.0;  m_halo.g  = 15.0/255.0;  m_halo.b  = 4.0/255.0;

        initref (m_pt.x, m_pt.y, img.Width(), img.Height(), matt) ;
    }

    virtual void ProcessPixel (FCObjImage& img, int x, int y, BYTE* pPixel)
    {
        double   hyp = FHypot (x-m_pt.x, y-m_pt.y) ;

        mcolor (pPixel, hyp); /* make color */
        mglow (pPixel, hyp);  /* make glow  */
        minner (pPixel, hyp); /* make inner */
        mouter (pPixel, hyp); /* make outer */
        mhalo (pPixel, hyp);  /* make halo  */

        for (int i=0 ; i < m_numref ; i++)
        {
            switch (m_ref[i].type)
            {
                case 1 : mrt1 (pPixel, m_ref + i, x, y); break;
                case 2 : mrt2 (pPixel, m_ref + i, x, y); break;
                case 3 : mrt3 (pPixel, m_ref + i, x, y); break;
                case 4 : mrt4 (pPixel, m_ref + i, x, y); break;
            }
        }
    }

    static double FHypot (double x, double y)
    {
        return sqrt (x*x + y*y) ;
    }

    POINT    m_pt ;
    Reflect  m_ref[19] ;
    int      m_numref ;
    double   m_scolor, m_sglow, m_sinner, m_souter, m_shalo ;
    FLOATRGB m_color, m_glow, m_inner, m_outer, m_halo ;
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Team Leader PhoXo
China China
graduate from University of Science and Technology of China at 2002.

Now I work at www.phoxo.com.

Comments and Discussions