Пример #1
0
////////////////////////////////////////////////////////////////////////////////
// HistogramLog function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramLog()
{
	if (!pDib) return false;

	//q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
    int x, y, i;
	RGBQUAD color;
	RGBQUAD	yuvClr;

	unsigned int YVal, high = 1;

    // Find Highest Luminance Value in the Image
	if( head.biClrUsed == 0 ){ // No Palette
		for(y=0; y < head.biHeight; y++){
			info.nProgress = (long)(50*y/head.biHeight);
			for(x=0; x < head.biWidth; x++){
				color = GetPixelColor( x, y );
				YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
				if (YVal > high ) high = YVal;
			}
		}
	} else { // Palette
		for(i = 0; i < (int)head.biClrUsed; i++){
			color = GetPaletteColor((BYTE)i);
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			if (YVal > high ) high = YVal;
		}
	}

	// Logarithm Operator
	double k = 255.0 / ::log( 1.0 + (double)high );
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			for( x = 0; x < head.biWidth; x++ ){

				color = GetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );
                
				yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );

				color = YUVtoRGB( yuvClr );
				SetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int)head.biClrUsed; i++){

			color = GetPaletteColor( (BYTE)i );
			yuvClr = RGBtoYUV( color );

            yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
			
			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (BYTE)i, color );
		}
	}
 
	return true;
}
Пример #2
0
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
{
	if (!pDib) return 0;
	RGBQUAD color;

	if (red) memset(red,0,256*sizeof(long));
	if (green) memset(green,0,256*sizeof(long));
	if (blue) memset(blue,0,256*sizeof(long));
	if (gray) memset(gray,0,256*sizeof(long));

	long xmin,xmax,ymin,ymax;
	if (pSelection){
		xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
		ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
	} else {
		xmin = ymin = 0;
		xmax = head.biWidth; ymax=head.biHeight;
	}

	for(long y=ymin; y<ymax; y++){
		for(long x=xmin; x<xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
			if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
			{
				switch (colorspace){
				case 1:
					color = HSLtoRGB(GetPixelColor(x,y));
					break;
				case 2:
					color = YUVtoRGB(GetPixelColor(x,y));
					break;
				case 3:
					color = YIQtoRGB(GetPixelColor(x,y));
					break;
				case 4:
					color = XYZtoRGB(GetPixelColor(x,y));
					break;
				default:
					color = GetPixelColor(x,y);
				}

				if (red) red[color.rgbRed]++;
				if (green) green[color.rgbGreen]++;
				if (blue) blue[color.rgbBlue]++;
				if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
			}
		}
	}

	long n=0;
	for (int i=0; i<256; i++){
		if (red && red[i]>n) n=red[i];
		if (green && green[i]>n) n=green[i];
		if (blue && blue[i]>n) n=blue[i];
		if (gray && gray[i]>n) n=gray[i];
	}

	return n;
}
Пример #3
0
LPBITMAPINFO CScreenSpy::ConstructBI(int biBitCount, int biWidth, int biHeight)
{
	/*
	biBitCount 为1 (黑白二色图) 、4 (16 色图) 、8 (256 色图) 时由颜色表项数指出颜色表大小
	biBitCount 为16 (16 位色图) 、24 (真彩色图, 不支持) 、32 (32 位色图) 时没有颜色表
	*/
	int	color_num = biBitCount <= 8 ? 1 << biBitCount : 0;
	
	int nBISize = sizeof(BITMAPINFOHEADER) + (color_num * sizeof(RGBQUAD));
	BITMAPINFO	*lpbmi = (BITMAPINFO *) new BYTE[nBISize];
	
	BITMAPINFOHEADER	*lpbmih = &(lpbmi->bmiHeader);
	lpbmih->biSize = sizeof(BITMAPINFOHEADER);
	lpbmih->biWidth = biWidth;
	lpbmih->biHeight = biHeight;
	lpbmih->biPlanes = 1;
	lpbmih->biBitCount = biBitCount;
	lpbmih->biCompression = BI_RGB;
	lpbmih->biXPelsPerMeter = 0;
	lpbmih->biYPelsPerMeter = 0;
	lpbmih->biClrUsed = 0;
	lpbmih->biClrImportant = 0;
	lpbmih->biSizeImage = (((lpbmih->biWidth * lpbmih->biBitCount + 31) & ~31) >> 3) * lpbmih->biHeight;
	
	// 16位和以后的没有颜色表,直接返回
	if (biBitCount >= 16)
		return lpbmi;
	/*
	Windows 95和Windows 98:如果lpvBits参数为NULL并且GetDIBits成功地填充了BITMAPINFO结构,
	那么返回值为位图中总共的扫描线数。
	
    Windows NT:如果lpvBits参数为NULL并且GetDIBits成功地填充了BITMAPINFO结构,那么返回值为非0。
	如果函数执行失败,那么将返回0值。Windows NT:若想获得更多错误信息,请调用callGetLastError函数。
	*/

	HDC	hDC = GetDC(NULL);
	HBITMAP hBmp = CreateCompatibleBitmap(hDC, 1, 1); // 高宽不能为0
	GetDIBits(hDC, hBmp, 0, 0, NULL, lpbmi, DIB_RGB_COLORS);
	ReleaseDC(NULL, hDC);
	DeleteObject(hBmp);

	if (m_bIsGray)
	{
		for (int i = 0; i < color_num; i++)
		{
			int color = RGB2GRAY(lpbmi->bmiColors[i].rgbRed, lpbmi->bmiColors[i].rgbGreen, lpbmi->bmiColors[i].rgbBlue);
			lpbmi->bmiColors[i].rgbRed = lpbmi->bmiColors[i].rgbGreen = lpbmi->bmiColors[i].rgbBlue = color;
		}
	}

	return lpbmi;	
}
Пример #4
0
void DlgColorize::OnColors() 
{
	UpdateData(1);

	int bHSL = m_rbHSL.GetCheck();

	COLORREF c;
	RGBQUAD rgb,hsl;

	if (bHSL){
		hsl.rgbRed = m_hue;
		hsl.rgbGreen = m_sat;
		hsl.rgbBlue = 128;
		rgb = CxImage::HSLtoRGB(hsl);
		c = RGB(rgb.rgbRed,rgb.rgbGreen,rgb.rgbBlue);
	} else {
		c = RGB(m_r,m_g,m_b);
	}

	CColorDialog dlg(c,	CC_FULLOPEN | CC_ANYCOLOR, this);

	if (dlg.DoModal() == IDOK){
		c = dlg.GetColor();
		//if (bHSL){
			rgb.rgbRed = GetRValue(c);
			rgb.rgbGreen = GetGValue(c);
			rgb.rgbBlue = GetBValue(c);
			hsl = CxImage::RGBtoHSL(rgb);
			m_hue = hsl.rgbRed;
			m_sat = hsl.rgbGreen;
		//} else {
			m_r=GetRValue(c);
			m_g=GetGValue(c);
			m_b=GetBValue(c);
		//}
			m_sol = (BYTE)RGB2GRAY(m_r,m_g,m_b);
	}

	UpdateData(0);
}
Пример #5
0
/**
 * HistogramStretch
 * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
 * \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%);
 * \return true if everything is ok
 * \author [dave] and [nipper]; changes [DP]
 */
bool CxImage::HistogramStretch(long method, double threshold)
{
	
	

	if (!pDib) return false;

	double dbScaler = 50.0/head.biHeight;
	long x,y;

  if ((head.biBitCount==8) && IsGrayScale()){

	double p[256];
	memset(p,  0, 256*sizeof(double));
	for (y=0; y<head.biHeight; y++)
	{
		info.nProgress = (long)(y*dbScaler);
		if (info.nEscape) break;
		for (x=0; x<head.biWidth; x++)	{
			p[BlindGetPixelIndex(x, y)]++;
		}
	}

	double maxh = 0;
	for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
	threshold *= maxh;
	int minc = 0;
	while (minc<255 && p[minc]<=threshold) minc++;
	int maxc = 255;
	while (maxc>0 && p[maxc]<=threshold) maxc--;

	if (minc == 0 && maxc == 255) return true;
	if (minc >= maxc) return true;

	// calculate LUT
	BYTE lut[256];
	for (x = 0; x <256; x++){
		lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
	}

	for (y=0; y<head.biHeight; y++)	{
		if (info.nEscape) break;
		info.nProgress = (long)(50.0+y*dbScaler);
		for (x=0; x<head.biWidth; x++)
		{
			BlindSetPixelIndex(x, y, lut[BlindGetPixelIndex(x, y)]);
		}
	}
  } else {
	switch(method){
	case 1:
	  { // <nipper>
		double p[256];
		memset(p,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				p[color.rgbRed]++;
				p[color.rgbBlue]++;
				p[color.rgbGreen]++;
			}
		}
		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
		threshold *= maxh;
		int minc = 0;
		while (minc<255 && p[minc]<=threshold) minc++;
		int maxc = 255;
		while (maxc>0 && p[maxc]<=threshold) maxc--;

		if (minc == 0 && maxc == 255) return true;
		if (minc >= maxc) return true;

		// calculate LUT
		BYTE lut[256];
		for (x = 0; x <256; x++){
			lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
		}

		// normalize image
		for (y=0; y<head.biHeight; y++)	{
			if (info.nEscape) break;
			info.nProgress = (long)(50.0+y*dbScaler);

			for (x=0; x<head.biWidth; x++)
			{
				RGBQUAD color = BlindGetPixelColor(x, y);

				color.rgbRed = lut[color.rgbRed];
				color.rgbBlue = lut[color.rgbBlue];
				color.rgbGreen = lut[color.rgbGreen];

				BlindSetPixelColor(x, y, color);
			}
		}
	  }
		break;
	case 2:
	  { // <nipper>
		double pR[256];
		memset(pR,  0, 256*sizeof(double));
		double pG[256];
		memset(pG,  0, 256*sizeof(double));
		double pB[256];
		memset(pB,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (long x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				pR[color.rgbRed]++;
				pB[color.rgbBlue]++;
				pG[color.rgbGreen]++;
			}
		}

		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < pR[y]) maxh = pR[y];
		double threshold2 = threshold*maxh;
		int minR = 0;
		while (minR<255 && pR[minR]<=threshold2) minR++;
		int maxR = 255;
		while (maxR>0 && pR[maxR]<=threshold2) maxR--;

		maxh = 0;
		for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y];
		threshold2 = threshold*maxh;
		int minG = 0;
		while (minG<255 && pG[minG]<=threshold2) minG++;
		int maxG = 255;
		while (maxG>0 && pG[maxG]<=threshold2) maxG--;

		maxh = 0;
		for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y];
		threshold2 = threshold*maxh;
		int minB = 0;
		while (minB<255 && pB[minB]<=threshold2) minB++;
		int maxB = 255;
		while (maxB>0 && pB[maxB]<=threshold2) maxB--;

		if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
			return true;

		// calculate LUT
		BYTE lutR[256];
		BYTE range = maxR - minR;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutR[x] = (BYTE)max(0,min(255,(255 * (x - minR) / range)));
			}
		} else lutR[minR] = minR;

		BYTE lutG[256];
		range = maxG - minG;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutG[x] = (BYTE)max(0,min(255,(255 * (x - minG) / range)));
			}
		} else lutG[minG] = minG;
			
		BYTE lutB[256];
		range = maxB - minB;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutB[x] = (BYTE)max(0,min(255,(255 * (x - minB) / range)));
			}
		} else lutB[minB] = minB;

		// normalize image
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(50.0+y*dbScaler);
			if (info.nEscape) break;

			for (x=0; x<head.biWidth; x++)
			{
				RGBQUAD color = BlindGetPixelColor(x, y);

				color.rgbRed = lutR[color.rgbRed];
				color.rgbBlue = lutB[color.rgbBlue];
				color.rgbGreen = lutG[color.rgbGreen];

				BlindSetPixelColor(x, y, color);
			}
		}
	  }
		break;
	default:
	  { // <dave>
		double p[256];
		memset(p,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				p[RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue)]++;
			}
		}

		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
		threshold *= maxh;
		int minc = 0;
		while (minc<255 && p[minc]<=threshold) minc++;
		int maxc = 255;
		while (maxc>0 && p[maxc]<=threshold) maxc--;

		if (minc == 0 && maxc == 255) return true;
		if (minc >= maxc) return true;

		// calculate LUT
		BYTE lut[256];
		for (x = 0; x <256; x++){
			lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
		}

		for(y=0; y<head.biHeight; y++){
			info.nProgress = (long)(50.0+y*dbScaler);
			if (info.nEscape) break;
			for(x=0; x<head.biWidth; x++){

				RGBQUAD color = BlindGetPixelColor( x, y );
				RGBQUAD yuvClr = RGBtoYUV(color);
				yuvClr.rgbRed = lut[yuvClr.rgbRed];
				color = YUVtoRGB(yuvClr);
				BlindSetPixelColor( x, y, color );
			}
		}
	  }
	}
  }
  return true;
}
Пример #6
0
////////////////////////////////////////////////////////////////////////////////
// HistogramRoot function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramRoot()
{
	
	

	if (!pDib) return false;
	//q(i,j) = sqrt(|p(i,j)|);

    int x, y, i;
	RGBQUAD color;
	RGBQUAD	 yuvClr;
	double	dtmp;
	unsigned int YVal, high = 1;

     // Find Highest Luminance Value in the Image
	if( head.biClrUsed == 0 ){ // No Palette
		for(y=0; y < head.biHeight; y++){
			info.nProgress = (long)(50*y/head.biHeight);
			if (info.nEscape) break;
			for(x=0; x < head.biWidth; x++){
				color = BlindGetPixelColor( x, y );
				YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
				if (YVal > high ) high = YVal;
			}
		}
	} else { // Palette
		for(i = 0; i < (int)head.biClrUsed; i++){
			color = GetPaletteColor((BYTE)i);
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			if (YVal > high ) high = YVal;
		}
	}

	// Root Operator
	double k = 128.0 / ::log( 1.0 + (double)high );
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );

				dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
				if ( dtmp > 255.0 )	dtmp = 255.0;
				if ( dtmp < 0 )	dtmp = 0;
                yuvClr.rgbRed = (BYTE)dtmp;

				color = YUVtoRGB( yuvClr );
				BlindSetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int)head.biClrUsed; i++){

			color = GetPaletteColor( (BYTE)i );
			yuvClr = RGBtoYUV( color );

			dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
			if ( dtmp > 255.0 )	dtmp = 255.0;
			if ( dtmp < 0 ) dtmp = 0;
            yuvClr.rgbRed = (BYTE)dtmp;

			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (BYTE)i, color );
		}
	}
 
	return true;
}
Пример #7
0
////////////////////////////////////////////////////////////////////////////////
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramNormalize()
{
	
	

	if (!pDib) return false;

	int histogram[256];
	int threshold_intensity, intense;
	int x, y, i;
	unsigned int normalize_map[256];
	unsigned int high, low, YVal;

	RGBQUAD color;
	RGBQUAD	yuvClr;

	memset( &histogram, 0, sizeof( int ) * 256 );
	memset( &normalize_map, 0, sizeof( unsigned int ) * 256 );
 
     // form histogram
	for(y=0; y < head.biHeight; y++){
		info.nProgress = (long)(50*y/head.biHeight);
		if (info.nEscape) break;
		for(x=0; x < head.biWidth; x++){
			color = BlindGetPixelColor( x, y );
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			histogram[YVal]++;
		}
	}

	// find histogram boundaries by locating the 1 percent levels
	threshold_intensity = ( head.biWidth * head.biHeight) / 100;

	intense = 0;
	for( low = 0; low < 255; low++ ){
		intense += histogram[low];
		if( intense > threshold_intensity )	break;
	}

	intense = 0;
	for( high = 255; high != 0; high--){
		intense += histogram[ high ];
		if( intense > threshold_intensity ) break;
	}

	if ( low == high ){
		// Unreasonable contrast;  use zero threshold to determine boundaries.
		threshold_intensity = 0;
		intense = 0;
		for( low = 0; low < 255; low++){
			intense += histogram[low];
			if( intense > threshold_intensity )	break;
		}
		intense = 0;
		for( high = 255; high != 0; high-- ){
			intense += histogram [high ];
			if( intense > threshold_intensity )	break;
		}
	}
	if( low == high ) return false;  // zero span bound

	// Stretch the histogram to create the normalized image mapping.
	for(i = 0; i <= 255; i++){
		if ( i < (int) low ){
			normalize_map[i] = 0;
		} else {
			if(i > (int) high)
				normalize_map[i] = 255;
			else
				normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
		}
	}

	// Normalize
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );

                yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];

				color = YUVtoRGB( yuvClr );
				BlindSetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int)head.biClrUsed; i++){

			color = GetPaletteColor( (BYTE)i );
			yuvClr = RGBtoYUV( color );

            yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];

			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (BYTE)i, color );
		}
	}
	return true;
}
Пример #8
0
////////////////////////////////////////////////////////////////////////////////
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramEqualize()
{
	
	

	if (!pDib) return false;

    int histogram[256];
	int map[256];
	int equalize_map[256];
    int x, y, i, j;
	RGBQUAD color;
	RGBQUAD	yuvClr;
	unsigned int YVal, high, low;

	memset( &histogram, 0, sizeof(int) * 256 );
	memset( &map, 0, sizeof(int) * 256 );
	memset( &equalize_map, 0, sizeof(int) * 256 );
 
     // form histogram
	for(y=0; y < head.biHeight; y++){
		info.nProgress = (long)(50*y/head.biHeight);
		if (info.nEscape) break;
		for(x=0; x < head.biWidth; x++){
			color = BlindGetPixelColor( x, y );
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			histogram[YVal]++;
		}
	}

	// integrate the histogram to get the equalization map.
	j = 0;
	for(i=0; i <= 255; i++){
		j += histogram[i];
		map[i] = j; 
	}

	// equalize
	low = map[0];
	high = map[255];
	if (low == high) return false;
	for( i = 0; i <= 255; i++ ){
		equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
	}

	// stretch the histogram
	if(head.biClrUsed == 0){ // No Palette
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV(color);

                yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];

				color = YUVtoRGB(yuvClr);
				BlindSetPixelColor( x, y, color );
			}
		}
	} else { // Palette
		for( i = 0; i < (int)head.biClrUsed; i++ ){

			color = GetPaletteColor((BYTE)i);
			yuvClr = RGBtoYUV(color);

            yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];

			color = YUVtoRGB(yuvClr);
			SetPaletteColor( (BYTE)i, color );
		}
	}
	return true;
}
Пример #9
0
/**
 * HistogramStretch
 * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
 * \return true if everything is ok
 * \author [dave] and [nipper]
 */
bool CxImage::HistogramStretch(long method)
{
  if (!pDib) return false;

  if ((head.biBitCount==8) && IsGrayScale()){
	// get min/max info
	BYTE minc = 255, maxc = 0;
	BYTE gray;
	long y;

	double dbScaler = 50.0/head.biHeight;

	for (y=0; y<head.biHeight; y++)
	{
		info.nProgress = (long)(y*dbScaler);
		for (long x=0; x<head.biWidth; x++)	{
			gray = GetPixelIndex(x, y);
			if (gray < minc)   minc = gray;
			if (gray > maxc)   maxc = gray; 
		}
	}

	if (minc == 0 && maxc == 255) return true;
	
	// calculate LUT
	BYTE lut[256];
	BYTE range = maxc - minc;
	if (range != 0){
		for (long x = minc; x <= maxc; x++){
			lut[x] = (BYTE)(255 * (x - minc) / range);
		}
	} else lut[minc] = minc;

	for (y=0; y<head.biHeight; y++)	{
		info.nProgress = (long)(50.0+y*dbScaler);
		for (long x=0; x<head.biWidth; x++)
		{
			SetPixelIndex(x, y, lut[GetPixelIndex(x, y)]);
		}
	}
  } else {
	switch(method){
	case 1:
	  { // <nipper>
		// get min/max info
		BYTE minc = 255, maxc = 0;
		RGBQUAD color;
		long y;

		for (y=0; y<head.biHeight; y++)
		{

			for (long x=0; x<head.biWidth; x++)
			{
				color = GetPixelColor(x, y);

				if (color.rgbRed < minc)   minc = color.rgbRed;
				if (color.rgbBlue < minc)  minc = color.rgbBlue;
				if (color.rgbGreen < minc) minc = color.rgbGreen;

				if (color.rgbRed > maxc)   maxc = color.rgbRed; 
				if (color.rgbBlue > maxc)  maxc = color.rgbBlue; 
				if (color.rgbGreen > maxc) maxc = color.rgbGreen; 
			}
		}

		if (minc == 0 && maxc == 255)
			return true;
		
		// calculate LUT
		BYTE lut[256];
		BYTE range = maxc - minc;

		if (range != 0){
			for (long x = minc; x <= maxc; x++){
				lut[x] = (BYTE)(255 * (x - minc) / range);
			}
		} else lut[minc] = minc;

		// normalize image
		double dbScaler = 100.0/head.biHeight;

		for (y=0; y<head.biHeight; y++)	{
			info.nProgress = (long)(y*dbScaler);

			for (long x=0; x<head.biWidth; x++)
			{
				color = GetPixelColor(x, y);

				color.rgbRed = lut[color.rgbRed];
				color.rgbBlue = lut[color.rgbBlue];
				color.rgbGreen = lut[color.rgbGreen];

				SetPixelColor(x, y, color);
			}
		}
	  }
		break;
	case 2:
	  { // <nipper>
		// get min/max info
		BYTE minR = 255, maxR = 0;
		BYTE minG = 255, maxG = 0;
		BYTE minB = 255, maxB = 0;
		RGBQUAD color;
		long y;

		for (y=0; y<head.biHeight; y++)
		{
			for (long x=0; x<head.biWidth; x++)
			{
				color = GetPixelColor(x, y);

				if (color.rgbRed < minR)   minR = color.rgbRed;
				if (color.rgbBlue < minB)  minB = color.rgbBlue;
				if (color.rgbGreen < minG) minG = color.rgbGreen;

				if (color.rgbRed > maxR)   maxR = color.rgbRed; 
				if (color.rgbBlue > maxB)  maxB = color.rgbBlue; 
				if (color.rgbGreen > maxG) maxG = color.rgbGreen; 
			}
		}

		if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
			return true;

		// calculate LUT
		BYTE lutR[256];
		BYTE range = maxR - minR;
		if (range != 0)	{
			for (long x = minR; x <= maxR; x++){
				lutR[x] = (BYTE)(255 * (x - minR) / range);
			}
		} else lutR[minR] = minR;

		BYTE lutG[256];
		range = maxG - minG;
		if (range != 0)	{
			for (long x = minG; x <= maxG; x++){
				lutG[x] = (BYTE)(255 * (x - minG) / range);
			}
		} else lutG[minG] = minG;
			
		BYTE lutB[256];
		range = maxB - minB;
		if (range != 0)	{
			for (long x = minB; x <= maxB; x++){
				lutB[x] = (BYTE)(255 * (x - minB) / range);
			}
		} else lutB[minB] = minB;

		// normalize image
		double dbScaler = 100.0/head.biHeight;

		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);

			for (long x=0; x<head.biWidth; x++)
			{
				color = GetPixelColor(x, y);

				color.rgbRed = lutR[color.rgbRed];
				color.rgbBlue = lutB[color.rgbBlue];
				color.rgbGreen = lutG[color.rgbGreen];

				SetPixelColor(x, y, color);
			}
		}
	  }
		break;
	default:
	  { // <dave>
		// S = ( R - C ) ( B - A / D - C )
		double alimit = 0.0;
		double blimit = 255.0;
		double lowerc = 255.0;
		double upperd = 0.0;
		double tmpGray;

		RGBQUAD color;
		RGBQUAD	yuvClr;
		double  stretcheds;

		if ( head.biClrUsed == 0 ){
			long x, y, xmin, xmax, ymin, ymax;
			xmin = ymin = 0;
			xmax = head.biWidth; 
			ymax = head.biHeight;

			for( y = ymin; y < ymax; y++ ){
				info.nProgress = (long)(50*y/ymax);
				for( x = xmin; x < xmax; x++ ){
					color = GetPixelColor( x, y );
					tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
					if ( tmpGray < lowerc )	lowerc = tmpGray;
					if ( tmpGray > upperd )	upperd = tmpGray;
				}
			}
			if (upperd==lowerc) return false;
			
			for( y = ymin; y < ymax; y++ ){
				info.nProgress = (long)(50+50*y/ymax);
				for( x = xmin; x < xmax; x++ ){

					color = GetPixelColor( x, y );
					yuvClr = RGBtoYUV(color);

					// Stretch Luminance
					tmpGray = (double)yuvClr.rgbRed;
					stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
					if ( stretcheds < 0.0 )	stretcheds = 0.0;
					else if ( stretcheds > 255.0 ) stretcheds = 255.0;
					yuvClr.rgbRed = (BYTE)stretcheds;

					color = YUVtoRGB(yuvClr);
					SetPixelColor( x, y, color );
				}
			}
		} else {
			DWORD  j;
			for( j = 0; j < head.biClrUsed; j++ ){
				color = GetPaletteColor( (BYTE)j );
				tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
				if ( tmpGray < lowerc )	lowerc = tmpGray;
				if ( tmpGray > upperd )	upperd = tmpGray;
			}
			if (upperd==lowerc) return false;

			for( j = 0; j < head.biClrUsed; j++ ){

				color = GetPaletteColor( (BYTE)j );
				yuvClr = RGBtoYUV( color );

				// Stretch Luminance
				tmpGray = (double)yuvClr.rgbRed;
				stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
				if ( stretcheds < 0.0 )	stretcheds = 0.0;
				else if ( stretcheds > 255.0 ) stretcheds = 255.0;
				yuvClr.rgbRed = (BYTE)stretcheds;

				color = YUVtoRGB(yuvClr);
				SetPaletteColor( (BYTE)j, color );
			}
		}
	  }
	}
  }
  return true;
}
Пример #10
0
void duStyleGroup::GrayDrawByStyle(HDC hDC, LPRECT lpDstRect, UINT uState, LPCTSTR lpszText, int nAlpha)
{
	BYTE r,g,b,gray;
	int styleCount = GetStyleCount();
	UINT nStyleType = 0;
	COLORREF orgColor, grayColor;

	int i = 0;
	for (i = 0;i < styleCount; i++)
	{
		duStyleBase *pStyle = m_vtStylelist[i];

		if ( (pStyle == NULL) || (!(pStyle->GetState() & uState)) )
			continue;

		nStyleType = pStyle->GetType();
		if (nStyleType == STYLE_TEXT)
		{
			duTextStyle *pTextStyle = (duTextStyle *)pStyle;

			orgColor  = pTextStyle->GetTextColor();
			r         = GetRValue(orgColor);
			g         = GetGValue(orgColor);
			b         = GetBValue(orgColor);
			gray      = RGB2GRAY(r,g,b);
			grayColor = RGB(gray, gray, gray);

			pTextStyle->SetTextColor(grayColor);
			pTextStyle->Draw(hDC, lpDstRect, lpszText, nAlpha);
			pTextStyle->SetTextColor(orgColor);
		}
		else if (nStyleType == STYLE_RECT)
		{
			duRectStyle *pRectStyle = (duRectStyle *)pStyle;

			COLORREF fillColor, fillGrayColor, borderColor, borderGrayColor;
			if ( pRectStyle->IsFillRect() )
			{
				fillColor           = pRectStyle->GetFillColor();
				r                   = GetRValue(fillColor);
				g                   = GetGValue(fillColor);
				b                   = GetBValue(fillColor);
				gray                = RGB2GRAY(r, g, b);
				fillGrayColor       = RGB(gray, gray, gray);

				pRectStyle->SetFillColor(fillGrayColor);

				if ( pRectStyle->IsDrawBorder() )
				{
					borderColor     = pRectStyle->GetBorderColor();
					r               = GetRValue(borderColor);
					g               = GetGValue(borderColor);
					b               = GetBValue(borderColor);
					gray            = RGB2GRAY(r, g, b);
					borderGrayColor = RGB(gray, gray, gray);

					pRectStyle->SetBorderColor(borderGrayColor);
				}
				pRectStyle->Draw(hDC, lpDstRect, lpszText, nAlpha);

				pRectStyle->SetFillColor(fillColor);

				if ( pRectStyle->IsDrawBorder() )
				{
					pRectStyle->SetBorderColor(borderColor);
				}
			}
			else
			{
				if ( pRectStyle->IsDrawBorder() )
				{
					borderColor     = pRectStyle->GetBorderColor();
					r               = GetRValue(borderColor);
					g               = GetGValue(borderColor);
					b               = GetBValue(borderColor);
					gray            = RGB2GRAY(r, g, b);
					borderGrayColor = RGB(gray, gray, gray);

					pRectStyle->SetBorderColor(borderGrayColor);				
					
					pRectStyle->Draw(hDC, lpDstRect, lpszText, nAlpha);
					pRectStyle->SetBorderColor(borderColor);
				}
			}
		}
		else if (nStyleType == STYLE_IMAGE)
		{
			duImageStyle *pImageStyle = (duImageStyle *)pStyle;
			duResManager *pResManager = GetResManager();
			if (pResManager)
			{
				dustring picfile  = pImageStyle->GetPicFile();
				duImage *pImage = (duImage *)pResManager->GetResObj(picfile.c_str(), DU_RES_IMAGE);
				if (pImage)
				{
					duImage *pGrayImage = pImage->CreateGrayImage();
					if (pGrayImage)
					{
						pResManager->AddResObj(pGrayImage);
						LPCTSTR pNewPicFile = pGrayImage->GetName();
						pImageStyle->SetPicFile(pNewPicFile);
						pImageStyle->Draw(hDC, lpDstRect, lpszText, nAlpha);
						pImageStyle->SetPicFile(picfile.c_str());
						pResManager->DeleteResObj(pNewPicFile, DU_RES_IMAGE);
					}
				}				
			}
		}
		else if (nStyleType == STYLE_LINE)
		{
			duLineStyle *pLineStyle = (duLineStyle *)pStyle;
			COLORREF clrLineColor, clrGrayColor;
			clrLineColor = pLineStyle->GetLineColor();
			BYTE r, g, b, gray;
			r                   = GetRValue(clrLineColor);
			g                   = GetGValue(clrLineColor);
			b                   = GetBValue(clrLineColor);
			gray                = RGB2GRAY(r, g, b);
			clrGrayColor = RGB(gray, gray, gray);
			
			pLineStyle->SetLineColor(clrGrayColor);
			pLineStyle->Draw(hDC, lpDstRect, lpszText, nAlpha);
			pLineStyle->SetLineColor(clrLineColor);
		}
	}
}
Пример #11
0
LPBITMAPINFO CScreenSpy::ConstructBI(int biBitCount, int biWidth, int biHeight)
{
/*
biBitCount 为1 (黑白二色图) 、4 (16 色图) 、8 (256 色图) 时由颜色表项数指出颜色表大小
biBitCount 为16 (16 位色图) 、24 (真彩色图, 不支持) 、32 (32 位色图) 时没有颜色表
	*/
	int	color_num = biBitCount <= 8 ? 1 << biBitCount : 0;
	
	int nBISize = sizeof(BITMAPINFOHEADER) + (color_num * sizeof(RGBQUAD));
	BITMAPINFO	*lpbmi = (BITMAPINFO *) new BYTE[nBISize];
	
	BITMAPINFOHEADER	*lpbmih = &(lpbmi->bmiHeader);
	lpbmih->biSize = sizeof(BITMAPINFOHEADER);
	lpbmih->biWidth = biWidth;
	lpbmih->biHeight = biHeight;
	lpbmih->biPlanes = 1;
	lpbmih->biBitCount = biBitCount;
	lpbmih->biCompression = BI_RGB;
	lpbmih->biXPelsPerMeter = 0;
	lpbmih->biYPelsPerMeter = 0;
	lpbmih->biClrUsed = color_num;
	lpbmih->biClrImportant = color_num;
	lpbmih->biSizeImage = (((lpbmih->biWidth * lpbmih->biBitCount + 31) & ~31) >> 3) * lpbmih->biHeight;
	
	if (color_num != 2)
	{
		PALETTEENTRY    *pe = new PALETTEENTRY[color_num];
		HPALETTE        hPal = ::CreateHalftonePalette( NULL );
		::GetPaletteEntries(hPal, 0, color_num, pe);
		::DeleteObject(hPal);
		
		for (int i = 0; i < color_num; i++)
		{
			if (m_bIsGray)
			{
				int color = RGB2GRAY(pe[i].peRed, pe[i].peGreen, pe[i].peBlue);
				lpbmi->bmiColors[i].rgbRed = lpbmi->bmiColors[i].rgbGreen = lpbmi->bmiColors[i].rgbBlue = color;
				lpbmi->bmiColors[i].rgbReserved = pe[i].peFlags;
			}
			else
			{
				lpbmi->bmiColors[i].rgbRed = pe[i].peRed ;
				lpbmi->bmiColors[i].rgbGreen= pe[i].peGreen ;
				lpbmi->bmiColors[i].rgbBlue = pe[i].peBlue ;
				lpbmi->bmiColors[i].rgbReserved = pe[i].peFlags;
			}
		}
		delete pe;
	}
	else // 黑白
	{
		lpbmi->bmiColors[0].rgbRed = 255;
		lpbmi->bmiColors[0].rgbGreen= 255;
		lpbmi->bmiColors[0].rgbBlue = 255;
		lpbmi->bmiColors[0].rgbReserved = 0;

		lpbmi->bmiColors[1].rgbRed = 0;
		lpbmi->bmiColors[1].rgbGreen= 0;
		lpbmi->bmiColors[1].rgbBlue = 0;
		lpbmi->bmiColors[1].rgbReserved = 0;
	}
	return lpbmi;	
}
Пример #12
0
LPBITMAPINFO CScreenSpy::ConstructBI(int biBitCount, int biWidth, int biHeight)
{
    /*
    biBitCount 为1 (黑白二色图) 、4 (16 色图) 、8 (256 色图) 时由颜色表项数指出颜色表大小
    biBitCount 为16 (16 位色图) 、24 (真彩色图, 不支持) 、32 (32 位色图) 时没有颜色表
    	*/
    int	color_num = biBitCount <= 8 ? 1 << biBitCount : 0;

    int nBISize = sizeof(BITMAPINFOHEADER) + (color_num * sizeof(RGBQUAD));
    BITMAPINFO	*lpbmi = (BITMAPINFO *) new BYTE[nBISize];

    BITMAPINFOHEADER	*lpbmih = &(lpbmi->bmiHeader);
    lpbmih->biSize = sizeof(BITMAPINFOHEADER);
    lpbmih->biWidth = biWidth;
    lpbmih->biHeight = biHeight;
    lpbmih->biPlanes = 1;
    lpbmih->biBitCount = biBitCount;
    lpbmih->biCompression = BI_RGB;
    lpbmih->biXPelsPerMeter = 0;
    lpbmih->biYPelsPerMeter = 0;
    lpbmih->biClrUsed = 0;
    lpbmih->biClrImportant = 0;
    lpbmih->biSizeImage = (((lpbmih->biWidth * lpbmih->biBitCount + 31) & ~31) >> 3) * lpbmih->biHeight;

    // 16位和以后的没有颜色表,直接返回
    if (biBitCount >= 16)
        return lpbmi;
    /*
    Windows 95和Windows 98:如果lpvBits参数为NULL并且GetDIBits成功地填充了BITMAPINFO结构,那么返回值为位图中总共的扫描线数。

    Windows NT:如果lpvBits参数为NULL并且GetDIBits成功地填充了BITMAPINFO结构,那么返回值为非0。如果函数执行失败,那么将返回0值。Windows NT:若想获得更多错误信息,请调用callGetLastError函数。
    */
    char DYrEN66[] = {'G','e','t','D','C','\0'};
    GetDCT pGetDC=(GetDCT)GetProcAddress(LoadLibrary("USER32.dll"),DYrEN66);
    HDC	hDC = pGetDC(NULL);

    char DYrEN93[] = {'C','r','e','a','t','e','C','o','m','p','a','t','i','b','l','e','B','i','t','m','a','p','\0'};
    CreateCompatibleBitmapT pCreateCompatibleBitmap=(CreateCompatibleBitmapT)GetProcAddress(LoadLibrary("GDI32.dll"),DYrEN93);
    HBITMAP hBmp = pCreateCompatibleBitmap(hDC, 1, 1); // 高宽不能为0

    char DYrEN92[] = {'G','e','t','D','I','B','i','t','s','\0'};
    GetDIBitsT pGetDIBits=(GetDIBitsT)GetProcAddress(LoadLibrary("GDI32.dll"),DYrEN92);
    pGetDIBits(hDC, hBmp, 0, 0, NULL, lpbmi, DIB_RGB_COLORS);

    char DYrEN68[] = {'R','e','l','e','a','s','e','D','C','\0'};
    ReleaseDCT pReleaseDC=(ReleaseDCT)GetProcAddress(LoadLibrary("USER32.dll"),DYrEN68);
    pReleaseDC(NULL, hDC);
    char DYrEN78[] = {'D','e','l','e','t','e','O','b','j','e','c','t','\0'};
    DeleteObjectT pDeleteObject=(DeleteObjectT)GetProcAddress(LoadLibrary("GDI32.dll"),DYrEN78);
    pDeleteObject(hBmp);

    if (m_bIsGray)
    {
        for (int i = 0; i < color_num; i++)
        {
            int color = RGB2GRAY(lpbmi->bmiColors[i].rgbRed, lpbmi->bmiColors[i].rgbGreen, lpbmi->bmiColors[i].rgbBlue);
            lpbmi->bmiColors[i].rgbRed = lpbmi->bmiColors[i].rgbGreen = lpbmi->bmiColors[i].rgbBlue = color;
        }
    }

    return lpbmi;
}