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

📄 ximatran.cpp

📁 用Cximage 库显示各种格式图片小程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//copy new image to the destination
	if (iDst) 
		iDst->Transfer(newImage);
	else 
		Transfer(newImage);
	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Reduces the number of bits per pixel to nbit (1, 4 or 8).
 * ppal points to a valid palette for the final image; if not supplied the function will use a standard palette.
 * ppal is not necessary for reduction to 1 bpp.
 */
bool CxImage::DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal, DWORD clrimportant)
{
	if (!pDib) return false;
	if (head.biBitCount <  nbit){
		strcpy(info.szLastError,"DecreaseBpp: target BPP greater than source BPP");
		return false;
	}
	if (head.biBitCount == nbit){
		if (clrimportant==0) return true;
		if (head.biClrImportant && (head.biClrImportant<clrimportant)) return true;
	}

	long er,eg,eb;
	RGBQUAD c,ce;

	CxImage tmp;
	tmp.CopyInfo(*this);
	tmp.Create(head.biWidth,head.biHeight,(WORD)nbit,info.dwType);
	if (clrimportant) tmp.SetClrImportant(clrimportant);
	if (!tmp.IsValid()){
		strcpy(info.szLastError,tmp.GetLastError());
		return false;
	}

#if CXIMAGE_SUPPORT_SELECTION
	tmp.SelectionCopy(*this);
#endif //CXIMAGE_SUPPORT_SELECTION

#if CXIMAGE_SUPPORT_ALPHA
	tmp.AlphaCopy(*this);
#endif //CXIMAGE_SUPPORT_ALPHA

	if (ppal) {
		if (clrimportant) {
			tmp.SetPalette(ppal,clrimportant);
		} else {
			tmp.SetPalette(ppal,1<<tmp.head.biBitCount);
		}
	} else {
		tmp.SetStdPalette();
	}

	for (long y=0;y<head.biHeight;y++){
		if (info.nEscape) break;
		info.nProgress = (long)(100*y/head.biHeight);
		for (long x=0;x<head.biWidth;x++){
			if (!errordiffusion){
				tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y));
			} else {
				c = BlindGetPixelColor(x,y);
				tmp.BlindSetPixelColor(x,y,c);

				ce = tmp.BlindGetPixelColor(x,y);
				er=(long)c.rgbRed - (long)ce.rgbRed;
				eg=(long)c.rgbGreen - (long)ce.rgbGreen;
				eb=(long)c.rgbBlue - (long)ce.rgbBlue;

				c = GetPixelColor(x+1,y);
				c.rgbRed = (BYTE)min(255L,max(0L,(long)c.rgbRed + ((er*7)/16)));
				c.rgbGreen = (BYTE)min(255L,max(0L,(long)c.rgbGreen + ((eg*7)/16)));
				c.rgbBlue = (BYTE)min(255L,max(0L,(long)c.rgbBlue + ((eb*7)/16)));
				SetPixelColor(x+1,y,c);
				int coeff=1;
				for(int i=-1; i<2; i++){
					switch(i){
					case -1:
						coeff=2; break;
					case 0:
						coeff=4; break;
					case 1:
						coeff=1; break;
					}
					c = GetPixelColor(x+i,y+1);
					c.rgbRed = (BYTE)min(255L,max(0L,(long)c.rgbRed + ((er * coeff)/16)));
					c.rgbGreen = (BYTE)min(255L,max(0L,(long)c.rgbGreen + ((eg * coeff)/16)));
					c.rgbBlue = (BYTE)min(255L,max(0L,(long)c.rgbBlue + ((eb * coeff)/16)));
					SetPixelColor(x+i,y+1,c);
				}
			}
		}
	}

	Transfer(tmp);
	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Increases the number of bits per pixel of the image.
 * \param nbit: 4, 8, 24
 */
bool CxImage::IncreaseBpp(DWORD nbit)
{
	if (!pDib) return false;
	switch (nbit){
	case 4:
		{
			if (head.biBitCount==4) return true;
			if (head.biBitCount>4) return false;

			CxImage tmp;
			tmp.CopyInfo(*this);
			tmp.Create(head.biWidth,head.biHeight,4,info.dwType);
			tmp.SetPalette(GetPalette(),GetNumColors());
			if (!tmp.IsValid()){
				strcpy(info.szLastError,tmp.GetLastError());
				return false;
			}


#if CXIMAGE_SUPPORT_SELECTION
			tmp.SelectionCopy(*this);
#endif //CXIMAGE_SUPPORT_SELECTION

#if CXIMAGE_SUPPORT_ALPHA
			tmp.AlphaCopy(*this);
#endif //CXIMAGE_SUPPORT_ALPHA

			for (long y=0;y<head.biHeight;y++){
				if (info.nEscape) break;
				for (long x=0;x<head.biWidth;x++){
					tmp.BlindSetPixelIndex(x,y,BlindGetPixelIndex(x,y));
				}
			}
			Transfer(tmp);
			return true;
		}
	case 8:
		{
			if (head.biBitCount==8) return true;
			if (head.biBitCount>8) return false;

			CxImage tmp;
			tmp.CopyInfo(*this);
			tmp.Create(head.biWidth,head.biHeight,8,info.dwType);
			tmp.SetPalette(GetPalette(),GetNumColors());
			if (!tmp.IsValid()){
				strcpy(info.szLastError,tmp.GetLastError());
				return false;
			}

#if CXIMAGE_SUPPORT_SELECTION
			tmp.SelectionCopy(*this);
#endif //CXIMAGE_SUPPORT_SELECTION

#if CXIMAGE_SUPPORT_ALPHA
			tmp.AlphaCopy(*this);
#endif //CXIMAGE_SUPPORT_ALPHA

			for (long y=0;y<head.biHeight;y++){
				if (info.nEscape) break;
				for (long x=0;x<head.biWidth;x++){
					tmp.BlindSetPixelIndex(x,y,BlindGetPixelIndex(x,y));
				}
			}
			Transfer(tmp);
			return true;
		}
	case 24:
		{
			if (head.biBitCount==24) return true;
			if (head.biBitCount>24) return false;

			CxImage tmp;
			tmp.CopyInfo(*this);
			tmp.Create(head.biWidth,head.biHeight,24,info.dwType);
			if (!tmp.IsValid()){
				strcpy(info.szLastError,tmp.GetLastError());
				return false;
			}

			if (info.nBkgndIndex>=0) //translate transparency
				tmp.info.nBkgndColor=GetPaletteColor((BYTE)info.nBkgndIndex);

#if CXIMAGE_SUPPORT_SELECTION
			tmp.SelectionCopy(*this);
#endif //CXIMAGE_SUPPORT_SELECTION

#if CXIMAGE_SUPPORT_ALPHA
			tmp.AlphaCopy(*this);
			if (AlphaPaletteIsValid() && !AlphaIsValid()) tmp.AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA

			for (long y=0;y<head.biHeight;y++){
				if (info.nEscape) break;
				for (long x=0;x<head.biWidth;x++){
					tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y),true);
				}
			}
			Transfer(tmp);
			return true;
		}
	}
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Converts the image to B&W using the desired method :
 * - 0 = Floyd-Steinberg
 * - 1 = Ordered-Dithering (4x4) 
 * - 2 = Burkes
 * - 3 = Stucki
 * - 4 = Jarvis-Judice-Ninke
 * - 5 = Sierra
 * - 6 = Stevenson-Arce
 * - 7 = Bayer (4x4 ordered dithering) 
 */
bool CxImage::Dither(long method)
{
	if (!pDib) return false;
	if (head.biBitCount == 1) return true;
	
	GrayScale();

	CxImage tmp;
	tmp.CopyInfo(*this);
	tmp.Create(head.biWidth, head.biHeight, 1, info.dwType);
	if (!tmp.IsValid()){
		strcpy(info.szLastError,tmp.GetLastError());
		return false;
	}

#if CXIMAGE_SUPPORT_SELECTION
	tmp.SelectionCopy(*this);
#endif //CXIMAGE_SUPPORT_SELECTION

#if CXIMAGE_SUPPORT_ALPHA
	tmp.AlphaCopy(*this);
#endif //CXIMAGE_SUPPORT_ALPHA

	switch (method){
	case 1:
	{
		// Multi-Level Ordered-Dithering by Kenny Hoff (Oct. 12, 1995)
		#define dth_NumRows 4
		#define dth_NumCols 4
		#define dth_NumIntensityLevels 2
		#define dth_NumRowsLessOne (dth_NumRows-1)
		#define dth_NumColsLessOne (dth_NumCols-1)
		#define dth_RowsXCols (dth_NumRows*dth_NumCols)
		#define dth_MaxIntensityVal 255
		#define dth_MaxDitherIntensityVal (dth_NumRows*dth_NumCols*(dth_NumIntensityLevels-1))

		int DitherMatrix[dth_NumRows][dth_NumCols] = {{0,8,2,10}, {12,4,14,6}, {3,11,1,9}, {15,7,13,5} };
		
		unsigned char Intensity[dth_NumIntensityLevels] = { 0,1 };                       // 2 LEVELS B/W
		//unsigned char Intensity[NumIntensityLevels] = { 0,255 };                       // 2 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,127,255 };                   // 3 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,85,170,255 };                // 4 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,63,127,191,255 };            // 5 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,51,102,153,204,255 };        // 6 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,42,85,127,170,213,255 };     // 7 LEVELS
		//unsigned char Intensity[NumIntensityLevels] = { 0,36,73,109,145,182,219,255 }; // 8 LEVELS
		int DitherIntensity, DitherMatrixIntensity, Offset, DeviceIntensity;
		unsigned char DitherValue;
  
		for (long y=0;y<head.biHeight;y++){
			info.nProgress = (long)(100*y/head.biHeight);
			if (info.nEscape) break;
			for (long x=0;x<head.biWidth;x++){

				DeviceIntensity = BlindGetPixelIndex(x,y);
				DitherIntensity = DeviceIntensity*dth_MaxDitherIntensityVal/dth_MaxIntensityVal;
				DitherMatrixIntensity = DitherIntensity % dth_RowsXCols;
				Offset = DitherIntensity / dth_RowsXCols;
				if (DitherMatrix[y&dth_NumRowsLessOne][x&dth_NumColsLessOne] < DitherMatrixIntensity)
					DitherValue = Intensity[1+Offset];
				else
					DitherValue = Intensity[0+Offset];

				tmp.BlindSetPixelIndex(x,y,DitherValue);
			}
		}
		break;
	}
	case 2:
	{
		//Burkes error diffusion (Thanks to Franco Gerevini)
		int TotalCoeffSum = 32;
		long error, nlevel, coeff=1;
		BYTE level;

		for (long y = 0; y < head.biHeight; y++) {
			info.nProgress = (long)(100 * y / head.biHeight);
			if (info.nEscape) 
				break;
			for (long x = 0; x < head.biWidth; x++) {
				level = BlindGetPixelIndex(x, y);
				if (level > 128) {
					tmp.SetPixelIndex(x, y, 1);
					error = level - 255;
				} else {
					tmp.SetPixelIndex(x, y, 0);
					error = level;
				}

				nlevel = GetPixelIndex(x + 1, y) + (error * 8) / TotalCoeffSum;
				level = (BYTE)min(255, max(0, (int)nlevel));
				SetPixelIndex(x + 1, y, level);
				nlevel = GetPixelIndex(x + 2, y) + (error * 4) / TotalCoeffSum;
				level = (BYTE)min(255, max(0, (int)nlevel));
				SetPixelIndex(x + 2, y, level);
				int i;
				for (i = -2; i < 3; i++) {
					switch (i) {
					case -2:
						coeff = 2;
						break;
					case -1:
						coeff = 4;
						break;
					case 0:
						coeff = 8; 
						break;
					case 1:
						coeff = 4; 
						break;
					case 2:
						coeff = 2; 
						break;
					}
					nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
					level = (BYTE)min(255, max(0, (int)nlevel));
					SetPixelIndex(x + i, y + 1, level);
				}
			}
		}
		break;
	}
	case 3:
	{
		//Stucki error diffusion (Thanks to Franco Gerevini)
		int TotalCoeffSum = 42;
		long error, nlevel, coeff=1;
		BYTE level;

		for (long y = 0; y < head.biHeight; y++) {
			info.nProgress = (long)(100 * y / head.biHeight);
			if (info.nEscape) 
				break;
			for (long x = 0; x < head.biWidth; x++) {
				level = BlindGetPixelIndex(x, y);
				if (level > 128) {
					tmp.SetPixelIndex(x, y, 1);
					error = level - 255;
				} else {
					tmp.SetPixelIndex(x, y, 0);
					error = level;
				}

				nlevel = GetPixelIndex(x + 1, y) + (error * 8) / TotalCoeffSum;
				level = (BYTE)min(255, max(0, (int)nlevel));
				SetPixelIndex(x + 1, y, level);
				nlevel = GetPixelIndex(x + 2, y) + (error * 4) / TotalCoeffSum;
				level = (BYTE)min(255, max(0, (int)nlevel));
				SetPixelIndex(x + 2, y, level);
				int i;
				for (i = -2; i < 3; i++) {
					switch (i) {
					case -2:
						coeff = 2;
						break;
					case -1:
						coeff = 4;
						break;
					case 0:
						coeff = 8; 
						break;
					case 1:
						coeff = 4; 
						break;
					case 2:
						coeff = 2; 
						break;
					}
					nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
					level = (BYTE)min(255, max(0, (int)nlevel));
					SetPixelIndex(x + i, y + 1, level);
				}
				for (i = -2; i < 3; i++) {
					switch (i) {
					case -2:
						coeff = 1;
						break;
					case -1:
						coeff = 2;
						break;
					case 0:
						coeff = 4; 
						break;
					case 1:
						coeff = 2; 
						break;
					case 2:
						coeff = 1; 
						break;
					}
					nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
					level = (BYTE)min(255, max(0, (int)nlevel));
					SetPixelIndex(x + i, y + 2, level);
				}

⌨️ 快捷键说明

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