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






3.20/5 (10 votes)
Do you want to know how does Photoshop and other stuff generate Gradeint Colors? Here you can find the easy and fast code
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); }