⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.h

📁 Windows 图形编程 书籍
💻 H
字号:
#pragma once

//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : image.h						                                     //
//  Description: Generic image processing algorithms and classes                     //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#include <math.h>
#include "Color.h"

// Abstract class for mapping single pixel and scan line
class KPixelMapper
{
	BYTE * m_pColor;	// point to color table BGR...
	int    m_nSize;		// size of an entry in the table 3 or 4
	int	   m_nCount;	// number of entries in the table

	// return true if data changed
	virtual bool MapRGB(BYTE & red, BYTE & green, BYTE & blue) = 0;

	// return true if data changed
	virtual bool MapIndex(BYTE & index)
	{
		MapRGB(m_pColor[index*m_nSize+2], 
			   m_pColor[index*m_nSize+1], 
			   m_pColor[index*m_nSize]);

		return false;
	}

public:

	KPixelMapper(void)
	{
		m_pColor = NULL;
		m_nSize  = 0;
		m_nCount = 0;
	}

	virtual ~ KPixelMapper()
	{
	}

	void SetColorTable(BYTE * pColor, int nEntrySize, int nCount)
	{
		m_pColor = pColor;
		m_nSize  = nEntrySize;
		m_nCount = nCount;
	}

	virtual bool StartLine(int line)
	{
		return true;
	}

	virtual void Map1bpp(BYTE * pBuffer, int width);
	virtual void Map2bpp(BYTE * pBuffer, int width);
	virtual void Map4bpp(BYTE * pBuffer, int width);
	virtual void Map8bpp(BYTE * pBuffer, int width);
	virtual void  Map555(BYTE * pBuffer, int width);
	virtual void  Map565(BYTE * pBuffer, int width);
	virtual void Map24bpp(BYTE * pBuffer, int width);
	virtual void Map32bpp(BYTE * pBuffer, int width);

};

typedef BYTE (* Operator)(BYTE red, BYTE green, BYTE blue);

class KDIB;
class KImage;

// Generic channel splitting class derived from CPixelMapper
// Controled by an operator function passed to CChannel::Split
class KChannel : public KPixelMapper
{
	Operator  m_Operator;
	int		  m_nBPS;
	
	BYTE * m_pBits;
	BYTE * m_pPixel;

	// return true if data changed
	virtual bool MapRGB(BYTE & red, BYTE & green, BYTE & blue)
	{
		* m_pPixel ++ = m_Operator(red, green, blue);

		return false;
	}

	virtual bool StartLine(int line)
	{
		m_pPixel = m_pBits + line * m_nBPS; // first pixel of a scanline

		return true;
	}

public:

	BITMAPINFO * Split(KImage & dib, Operator oper);
};


// RGB channel splitting operators

inline BYTE TakeRed(BYTE red, BYTE green, BYTE blue)
{
	return red;
}

inline BYTE TakeGreen(BYTE red, BYTE green, BYTE blue)
{
	return green;
}

inline BYTE TakeBlue(BYTE red, BYTE green, BYTE blue)
{
	return blue;
}

// KCMY channel splitting operators
inline BYTE TakeK(BYTE red, BYTE green, BYTE blue)
{
	// min ( 255-red, 255-green, 255-blue)
	if ( red < green )
		if ( green < blue )
			return 255 - blue;
		else
			return 255 - green;
	else
		return 255 - red;
}

inline BYTE TakeC(BYTE red, BYTE green, BYTE blue)
{
	return 255 - red; // - TakeK(red, green, blue);
}

inline BYTE TakeM(BYTE red, BYTE green, BYTE blue)
{
	return 255 - green; //  - TakeK(red, green, blue);
}

inline BYTE TakeY(BYTE red, BYTE green, BYTE blue)
{
	return 255 - blue; //  - TakeK(red, green, blue);
}

// HLS channel splitting operators
inline BYTE TakeH(BYTE red, BYTE green, BYTE blue)
{
	KColor color(red, green, blue);
	color.ToHLS();

	return (BYTE) (color.hue * 255 / 360);
}

inline BYTE TakeL(BYTE red, BYTE green, BYTE blue)
{
	KColor color(red, green, blue);
	color.ToHLS();

	return (BYTE) (color.lightness * 255);
}

inline BYTE TakeS(BYTE red, BYTE green, BYTE blue)
{
	KColor color(red, green, blue);
	color.ToHLS();

	return (BYTE) (color.saturation * 255);
}


// 0.299 * red + 0.587 * green + 0.114 * blue 
inline void MaptoGray(BYTE & red, BYTE & green, BYTE & blue)
{
	red   = ( red * 77 + green * 150 + blue * 29 + 128 ) / 256;
	green = red;
	blue  = red;
}

inline void LightenColor(BYTE & red, BYTE & green, BYTE & blue)
{
	KColor color( red, green, blue );
	color.ToHLS();

	color.lightness = sqrt(color.lightness);
	color.ToRGB();

	red   = color.red;
	green = color.green;
	blue  = color.blue;
}


// RGB Histogram class derived from CPixelMapper
class KHistogram : public KPixelMapper
{
	int		  m_FreqRed[256];
	int		  m_FreqGreen[256];
	int		  m_FreqBlue[256];
	int		  m_FreqGray[256];

	// return true if data changed
	virtual bool MapRGB(BYTE & red, BYTE & green, BYTE & blue)
	{
		m_FreqRed[red]     ++;
		m_FreqGreen[green] ++;
		m_FreqBlue[blue]   ++;
		m_FreqGray[(red * 77 + green * 150 + blue * 29 + 128 ) / 256] ++;

		return false;
	}

public:

	void Sample(KImage & dib);
};


// Abstract class for image convolution for single pixel and scan line
class KFilter
{
	int	m_nHalf;

	virtual BYTE Kernel(BYTE * pPixel, int dx, int dy) = 0;

public:

	int GetHalf(void) const
	{
		return m_nHalf;
	}

	KFilter(void)
	{
		m_nHalf = 1;
	}

	virtual ~ KFilter()
	{
	}

	virtual void DescribeFilter(HDC hDC, int x, int y)
	{
	}

	virtual void  Filter8bpp(BYTE * pDest, BYTE * pSource, int nWidth, int dy);
	virtual void Filter24bpp(BYTE * pDest, BYTE * pSource, int nWidth, int dy);
	virtual void Filter32bpp(BYTE * pDest, BYTE * pSource, int nWidth, int dy);
};


void Describe33Filter(HDC hDC, int x, int y, const int * matrix, TCHAR * name, int weight, int add);

template <int k00, int k01, int k02, int k10, int k11, int k12, int k20, int k21, int k22, 
		  int weight, int add, bool checkbound, TCHAR * name>
class K33Filter : public KFilter
{
	virtual BYTE Kernel(BYTE * pPixel, int dx, int dy)
	{
		int rslt = ( pPixel[-dy-dx] * k00 + pPixel[-dy] * k01 + pPixel[-dy+dx] * k02 +
			         pPixel[   -dx] * k10 + pPixel[0]   * k11 + pPixel[   +dx] * k12 +
			         pPixel[ dy-dx] * k20 + pPixel[dy]  * k21 + pPixel[ dy+dx] * k22 ) / weight + add;

		if ( checkbound )
			if ( rslt < 0 )
				return 0;
			else if ( rslt > 255 )
				return 255;

		return rslt;
	}

	void DescribeFilter(HDC hDC, int x, int y)
	{
		const int matrix[] = { k00, k01, k02, k10, k11, k12, k20, k21, k22 };
	
		Describe33Filter(hDC, x, y, matrix, name, weight, add);
	}
};


// Mimimum to grow the darker region
class KErosion : public KFilter
{
	inline void smaller(BYTE &x, BYTE y)
	{
		if ( y < x ) x = y;
	}

	BYTE Kernel(BYTE * pPixel, int dx, int dy)
	{
		BYTE m = pPixel[-dy-dx];

		smaller(m, pPixel[-dy]);
		smaller(m, pPixel[-dy+dx]);
		smaller(m, pPixel[   -dx]);
		smaller(m, pPixel[   +dx]);
		smaller(m, pPixel[ dy-dx]);
		smaller(m, pPixel[dy]);
		smaller(m, pPixel[ dy+dx]);
		
		return min(pPixel[0], m); // /2;
	}

	void DescribeFilter(HDC hDC, int x, int y)
	{
		Describe33Filter(hDC, x, y, NULL, _T("Erosion"), 0, 0);
	}
};

// Maximum to grow the light region
class KDilation : public KFilter
{
	inline void bigger(BYTE &x, BYTE y)
	{
		if ( y > x ) x = y;
	}

	BYTE Kernel(BYTE * pPixel, int dx, int dy)
	{
		BYTE m = pPixel[-dy-dx];

		bigger(m, pPixel[-dy]);
		bigger(m, pPixel[-dy+dx]);
		bigger(m, pPixel[   -dx]);
		bigger(m, pPixel[   +dx]);
		bigger(m, pPixel[ dy-dx]);
		bigger(m, pPixel[dy]);
		bigger(m, pPixel[ dy+dx]);
		
		return max( pPixel[0], m ); // /2;
	}

	void DescribeFilter(HDC hDC, int x, int y)
	{
		Describe33Filter(hDC, x, y, NULL, _T("Dilation"), 0, 0);
	}
};


// Maximum to grow the light region, then substract
class KOutline : public KFilter
{
	inline void bigger(BYTE &x, BYTE y)
	{
		if ( y > x ) x = y;
	}

	BYTE Kernel(BYTE * pPixel, int dx, int dy)
	{
		BYTE m = pPixel[0];
		
		bigger(m, pPixel[-dy-dx]);
		bigger(m, pPixel[-dy]);
		bigger(m, pPixel[-dy+dx]);
		bigger(m, pPixel[   -dx]);
		bigger(m, pPixel[   +dx]);
		bigger(m, pPixel[ dy-dx]);
		bigger(m, pPixel[dy]);
		bigger(m, pPixel[ dy+dx]);
		
		return m - pPixel[0];
	}

	void DescribeFilter(HDC hDC, int x, int y)
	{
		Describe33Filter(hDC, x, y, NULL, _T("Outline"), 0, 0);
	}
};


typedef enum
{
	FILTER_IDENTITY,

	FILTER_SMOOTH,
	FILTER_GUASSIANSMOOTH,
	FILTER_SHARPENING,
	FILTER_LAPLASION,
	FILTER_EMBOSS135,
	FILTER_EMBOSS90,
	FILTER_DILATION,
	FILTER_EROSION,
	FILTER_OUTLINE,
	
	FILTER_LAST = FILTER_OUTLINE
};

KFilter * StockFilters[];


class KImage : public KDIB
{
public:
	bool ToGreyScale(void);
	bool Lighten(void);
	bool GammaCorrect(double redgamma, double greengamma, double bluegamma);

	BITMAPINFO * SplitChannel(Operator oper);

	bool	PixelTransform(KPixelMapper & map);
	bool	Convolution(KFilter * pFilter);
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -