Click here to Skip to main content
15,886,625 members
Articles / Desktop Programming / MFC
Article

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

Rate me:
Please Sign up or sign in to vote.
3.20/5 (10 votes)
5 Feb 2004CPOL 65.5K   1.1K   25   10
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Jordan Jordan
Mohammad Ahmad Khaleel Gdeisat: Born in Irbid-Jordan in 1984. Started programming in 1998 on Visual Basic and interested in it. I joined the Computer Engineering Dept in 2002 and also started programming for windows using Visual C++ 6 and MFC. I love cats, cool animals and jokes.

I am very glad to be a member of such a great programming society and I hope that Arabs and Muslims will work very hard to achieve thier respective position in computer technology and all other sciences Smile | :) .

Comments and Discussions

 
GeneralMy vote of 5 Pin
ahmed_20032-Dec-10 16:49
ahmed_20032-Dec-10 16:49 
GeneralThank you so much! Pin
tina_nguyen6-May-06 3:17
tina_nguyen6-May-06 3:17 
GeneralExplanation Pin
Mohammad A Gdeisat8-Feb-04 23:24
Mohammad A Gdeisat8-Feb-04 23:24 
GeneralHave I told you anything ? Pin
Kochise9-Feb-04 21:20
Kochise9-Feb-04 21:20 
GeneralRe: Have I told you anything ? Pin
Mohammad A Gdeisat14-Feb-04 7:59
Mohammad A Gdeisat14-Feb-04 7:59 
GeneralSearch first. Pin
Shog97-Feb-04 19:44
sitebuilderShog97-Feb-04 19:44 
GeneralRe: Search first. Pin
NormDroid8-Feb-04 21:25
professionalNormDroid8-Feb-04 21:25 
GeneralRe: Search first. Pin
grigri13-Feb-04 5:08
grigri13-Feb-04 5:08 
GeneralRe: Search first. Pin
Mohammad A Gdeisat13-Feb-04 9:13
Mohammad A Gdeisat13-Feb-04 9:13 
GeneralRe: Search first. Pin
grigri14-Feb-04 4:39
grigri14-Feb-04 4:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.