Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to make a gradeint-colored Image - Fast and Easy

0.00/5 (No votes)
5 Feb 2004 1  
Do you want to know how does Photoshop and other stuff generate Gradeint Colors? Here you can find the easy and fast code

Sample Image - Pic.jpg

Introduction

This article explains how to draw gradient colors in your Windows application. This article requires some basic knowledge of MFC classes and GUI. The code below is very easy and well-commented - I have commented out every sentence that I thought it might be helpful to comment it out. All the idea is to get RGB values of two colors, and then draw and fill rectangles using these colors and all 256 colors that lie between them to create a gradient image like ones we see in Setup and Installation programs.

I am still a beginner programmer but if you have any comments or suggestions related to this article then I would be glad to hearing from you. Also, if you have any questions, you can contact me at mohgdeisat@hotmail.com.

Gradient.h

#if !defined(AFX_GRADIENT1_H__39634012_8104_4550_A02B_65C0C7553A60__INCLUDED_)
#define AFX_GRADIENT1_H__39634012_8104_4550_A02B_65C0C7553A60__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CGradient  
{
public:
    CGradient(CSize=CSize(800,600));
    virtual ~CGradient();
    //members

    void PrepareVertical(CDC *pDC,UINT RTop,
      UINT GTop,UINT BTOP,UINT RBot,UINT GBot,UINT BBot);
    void PrepareHorizontal(CDC *pDC,UINT RRight, 
      UINT GRight,UINT BRight,UINT RLeft,UINT GLeft,UINT BLeft);
    CSize GetDimensions();
    void  SetDimensions(CSize Size);
    void Draw(CDC *pDC, int xDest,int yDest,int xSrc, 
      int ySrc, int Width, int Height,DWORD Rop);

protected:
    CDC *m_dcMem;
    CSize m_Size;


};

#endif
// !defined(AFX_GRADIENT1_H__39634012_8104_4550_A02B_65C0C7553A60__INCLUDED_)

And the class implementation goes here:

// Gradient1.cpp: implementation of the CGradient class.

//

//////////////////////////////////////////////////////////////////////


#include "stdafx.h"

#include "Gradient.h"

#include "Gradient1.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////


CGradient::CGradient(CSize Size)
{
    m_Size=Size;
    m_dcMem=NULL;
}

CGradient::~CGradient()
{
    if(m_dcMem!=NULL)
        delete m_dcMem;
}
CSize CGradient::GetDimensions()
{
    return m_Size;
}

void  CGradient::SetDimensions(CSize Size)
{
    m_Size=Size;
}

void CGradient::PrepareVertical(CDC *pDC,UINT RTop, 
   UINT GTop,UINT BTop,UINT RBot,UINT GBot,UINT BBot)
{
    //Here we will create a memory bitmap and draw the colored bitmap on it

    //using my pretty Algorithm for generating colors.


    //if we have already a drawn DC then delete it so we will not have a

    //memory leak


    if(m_dcMem!=NULL)
    {
        delete m_dcMem;
    }

    //create the Memory Bitmap

    CBitmap Bitmap;
    m_dcMem=new CDC;    //new Device Context

    m_dcMem->CreateCompatibleDC(pDC);    //Make it Compatible with pDC

    m_dcMem->SetMapMode(MM_TEXT);        //Pixels Mapping Mode

    //Make the Bitmap compatible with the memory DC

    Bitmap.CreateCompatibleBitmap(pDC,m_Size.cx,m_Size.cy);    
    //Select the bitmap into the memory DC

    m_dcMem->SelectObject(&Bitmap);
    ////////////////////////////////////////////////////////////////

    ////Drawing The Gradient in a MemDC

    ////////////////////////////////////////////////////////////////

    //ALGORITHM:

    //We will have the RGB values of the color at which we will start

    //and the RGB values of the color at which we will end

    //we will fill 256 rectangles using all colors that lie between

    //these two colors. this is done by moving the R,G, and B values slowly

    //from the Starting color to the Ending Color.

    //For example: if we have RTop=100 and RBot=150 then we will draw 256

    //rectangles colored with the R-values of 100,100+(150-100)/256,

    //100+2*(150-100)/256,100+3*(150-100)/256,...

    //and the same will happen to G and B values.


    //rStep,gStep, and bStep are variables that will be used

    //to hold the values at which R,G,B will be changed respectivily

    //For example: if we have RTop=100 and RBot=150 then 

    //rStep=(150-100)/256 so when we start at R=100 and draw 256 rectangles

    //we will end at R=150 when we finish drawing these rectangles

    double rStep,gStep,bStep;
    double rCount,gCount,bCount;
    double RectHeight=m_Size.cy/256.0;
    const int NUM_COLORS=256;
    //We will start counting from TopColor to BottomColor

    //So we give an initial value of the TopColor

    rCount=RTop;
    gCount=GTop;
    bCount=BTop;
    //Calcualte the step of R,G,B values

    rStep=-((double)RTop-RBot)/NUM_COLORS;
    gStep=-((double)GTop-GBot)/NUM_COLORS;
    bStep=-((double)BTop-BBot)/NUM_COLORS;
    for(int ColorCount=0;ColorCount<NUM_COLORS;ColorCount++)
    {
        //Draw using current RGB values and Change RGB values

        //to represent the next color in the chain

        m_dcMem->FillRect(CRect(0,ColorCount*RectHeight,
           m_Size.cx,(ColorCount+1)*RectHeight),
           &CBrush(RGB(rCount,gCount,bCount)));
        rCount+=rStep;
        gCount+=gStep;
        bCount+=bStep;
    }
}

void CGradient::PrepareHorizontal(CDC *pDC,UINT RLeft, 
  UINT GLeft,UINT BLeft,UINT RRight,UINT GRight,UINT BRight)
{
    if(m_dcMem!=NULL)
    {
        delete m_dcMem;
    }

    CBitmap Bitmap;
    m_dcMem=new CDC;
    m_dcMem->CreateCompatibleDC(pDC);
    m_dcMem->SetMapMode(MM_TEXT);
    Bitmap.CreateCompatibleBitmap(pDC,m_Size.cx,m_Size.cy);
    m_dcMem->SelectObject(&Bitmap);
    ////////////////////////////////////////////////////////////////

    ////Drawing The Gradient in a MemDC

    double rStep,gStep,bStep;
    double rCount,gCount,bCount;
    double RectWidth=m_Size.cx/256.0;
    const int NUM_COLORS=256;
    rCount=RRight;
    gCount=GRight;
    bCount=BRight;
    rStep=-((double)RRight-RLeft)/NUM_COLORS;
    gStep=-((double)GRight-GLeft)/NUM_COLORS;
    bStep=-((double)BRight-BLeft)/NUM_COLORS;

    for(int ColorCount=0;ColorCount<NUM_COLORS;ColorCount++)
    {
        m_dcMem->FillRect(CRect(ColorCount*RectWidth,
           0,(ColorCount+1)*RectWidth,m_Size.cy),
           &CBrush(RGB(rCount,gCount,bCount)));
        rCount+=rStep;
        gCount+=gStep;
        bCount+=bStep;
    }
}

void CGradient::Draw(CDC *pDC, int xDest,int yDest,
   int xSrc, int ySrc, int Width, int Height,DWORD Rop)
{
    //Use BitBlt to Draw on a DC

    
    pDC->BitBlt(xDest,yDest,Width,Height,m_dcMem,xSrc,ySrc,Rop);

}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here