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

📄 ximatran.cpp

📁 对CFileException进行修改后 这个血管提取的程序已经可以在VC8下面编译了 但是还有点内存泄露 没有进行修正 等有时间了在进行修改
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						color.rgbBlue = (BYTE)(255-color.rgbBlue);
						SetPixelColor(x,y,color);
					}
				}
			}
		}
		//<DP> invert transparent color too
		info.nBkgndColor.rgbBlue = (BYTE)(255-info.nBkgndColor.rgbBlue);
		info.nBkgndColor.rgbGreen = (BYTE)(255-info.nBkgndColor.rgbGreen);
		info.nBkgndColor.rgbRed = (BYTE)(255-info.nBkgndColor.rgbRed);
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_TRANSFORMATION
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
bool CxImage::Rotate(float angle, CxImage* iDst)
{
	if (!pDib) return false;

	//  Copyright (c) 1996-1998 Ulrich von Zadow

	// Negative the angle, because the y-axis is negative.
	double ang = -angle*acos((float)0)/90;
	int newWidth, newHeight;
	int nWidth = GetWidth();
	int nHeight= GetHeight();
	double cos_angle = cos(ang);
	double sin_angle = sin(ang);

	// Calculate the size of the new bitmap
	POINT p1={0,0};
	POINT p2={nWidth,0};
	POINT p3={0,nHeight};
	POINT p4={nWidth-1,nHeight};
	POINT newP1,newP2,newP3,newP4, leftTop, rightTop, leftBottom, rightBottom;

	newP1.x = p1.x;
	newP1.y = p1.y;
	newP2.x = (long)floor(p2.x*cos_angle - p2.y*sin_angle);
	newP2.y = (long)floor(p2.x*sin_angle + p2.y*cos_angle);
	newP3.x = (long)floor(p3.x*cos_angle - p3.y*sin_angle);
	newP3.y = (long)floor(p3.x*sin_angle + p3.y*cos_angle);
	newP4.x = (long)floor(p4.x*cos_angle - p4.y*sin_angle);
	newP4.y = (long)floor(p4.x*sin_angle + p4.y*cos_angle);

	leftTop.x = min(min(newP1.x,newP2.x),min(newP3.x,newP4.x));
	leftTop.y = min(min(newP1.y,newP2.y),min(newP3.y,newP4.y));
	rightBottom.x = max(max(newP1.x,newP2.x),max(newP3.x,newP4.x));
	rightBottom.y = max(max(newP1.y,newP2.y),max(newP3.y,newP4.y));
	leftBottom.x = leftTop.x;
	leftBottom.y = 2+rightBottom.y;
	rightTop.x = 2+rightBottom.x;
	rightTop.y = leftTop.y;

	newWidth = rightTop.x - leftTop.x;
	newHeight= leftBottom.y - leftTop.y;
	CxImage imgDest;
	imgDest.CopyInfo(*this);
	imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
	imgDest.SetPalette(GetPalette());

#if CXIMAGE_SUPPORT_ALPHA
	if(AlphaIsValid())	//MTA: Fix for rotation problem when the image has an alpha channel
	{
		imgDest.AlphaCreate();
		imgDest.AlphaClear();
	}
#endif //CXIMAGE_SUPPORT_ALPHA

	int x,y,newX,newY,oldX,oldY;

	if (head.biClrUsed==0){ //RGB
		for (y = leftTop.y, newY = 0; y<=leftBottom.y; y++,newY++){
			info.nProgress = (long)(100*newY/newHeight);
			if (info.nEscape) break;
			for (x = leftTop.x, newX = 0; x<=rightTop.x; x++,newX++){
				oldX = (long)(x*cos_angle + y*sin_angle - 0.5);
				oldY = (long)(y*cos_angle - x*sin_angle - 0.5);
				imgDest.SetPixelColor(newX,newY,GetPixelColor(oldX,oldY));
#if CXIMAGE_SUPPORT_ALPHA
				imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY));				//MTA: copy the alpha value
#endif //CXIMAGE_SUPPORT_ALPHA
			}
		}
	} else { //PALETTE
		for (y = leftTop.y, newY = 0; y<=leftBottom.y; y++,newY++){
			info.nProgress = (long)(100*newY/newHeight);
			if (info.nEscape) break;
			for (x = leftTop.x, newX = 0; x<=rightTop.x; x++,newX++){
				oldX = (long)(x*cos_angle + y*sin_angle - 0.5);
				oldY = (long)(y*cos_angle - x*sin_angle - 0.5);
				imgDest.SetPixelIndex(newX,newY,GetPixelIndex(oldX,oldY));
#if CXIMAGE_SUPPORT_ALPHA
				imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY));				//MTA: copy the alpha value
#endif //CXIMAGE_SUPPORT_ALPHA
			}
		}
	}
	//select the destination
	if (iDst) iDst->Transfer(imgDest);
	else Transfer(imgDest);

	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Rotates image around it's center.
 * Method can use interpolation with paletted images, but does not change pallete, so results vary.
 * (If you have only four colours in a palette, there's not much room for interpolation.)
 * 
 * \param  angle - angle in degrees (positive values rotate clockwise)
 * \param  *iDst - destination image (if null, this image is changed)
 * \param  inMethod - interpolation method used
 *              (IM_NEAREST_NEIGHBOUR produces aliasing (fast), IM_BILINEAR softens picture a bit (slower)
 *               IM_SHARPBICUBIC is slower and produces some halos...)
 * \param  ofMethod - overflow method (how to choose colour of pixels that have no source)
 * \param  replColor - replacement colour to use (OM_COLOR, OM_BACKGROUND with no background colour...)
 * \param  optimizeRightAngles - call faster methods for 90, 180, and 270 degree rotations. Faster methods
 *                         are called for angles, where error (in location of corner pixels) is less
 *                         than 0.25 pixels.
 * \param  bKeepOriginalSize - rotates the image without resizing.
 *
 * \author ***bd*** 2.2004
 */
bool CxImage::Rotate2(float angle, 
                       CxImage *iDst, 
                       InterpolationMethod inMethod, 
                       OverflowMethod ofMethod, 
                       RGBQUAD *replColor,
                       bool const optimizeRightAngles,
					   bool const bKeepOriginalSize)
{
	if (!pDib) return false;					//no dib no go
	
	double ang = -angle*acos(0.0f)/90.0f;		//convert angle to radians and invert (positive angle performs clockwise rotation)
	float cos_angle = (float) cos(ang);			//these two are needed later (to rotate)
	float sin_angle = (float) sin(ang);
	
	//Calculate the size of the new bitmap (rotate corners of image)
	CxPoint2 p[4];								//original corners of the image
	p[0]=CxPoint2(-0.5f,-0.5f);
	p[1]=CxPoint2(GetWidth()-0.5f,-0.5f);
	p[2]=CxPoint2(-0.5f,GetHeight()-0.5f);
	p[3]=CxPoint2(GetWidth()-0.5f,GetHeight()-0.5f);
	CxPoint2 newp[4];								//rotated positions of corners
	//(rotate corners)
	if (bKeepOriginalSize){
		for (int i=0; i<4; i++) {
			newp[i].x = p[i].x;
			newp[i].y = p[i].y;
		}//for
	} else {
		for (int i=0; i<4; i++) {
			newp[i].x = (p[i].x*cos_angle - p[i].y*sin_angle);
			newp[i].y = (p[i].x*sin_angle + p[i].y*cos_angle);
		}//for i
		
		if (optimizeRightAngles) { 
			//For rotations of 90, -90 or 180 or 0 degrees, call faster routines
			if (newp[3].Distance(CxPoint2(GetHeight()-0.5f, 0.5f-GetWidth())) < 0.25) 
				//rotation right for circa 90 degrees (diagonal pixels less than 0.25 pixel away from 90 degree rotation destination)
				return RotateRight(iDst);
			if (newp[3].Distance(CxPoint2(0.5f-GetHeight(), -0.5f+GetWidth())) < 0.25) 
				//rotation left for ~90 degrees
				return RotateLeft(iDst);
			if (newp[3].Distance(CxPoint2(0.5f-GetWidth(), 0.5f-GetHeight())) < 0.25) 
				//rotation left for ~180 degrees
				return Rotate180(iDst);
			if (newp[3].Distance(p[3]) < 0.25) {
				//rotation not significant
				if (iDst) iDst->Copy(*this);		//copy image to iDst, if required
				return true;						//and we're done
			}//if
		}//if
	}//if

	//(read new dimensions from location of corners)
	float minx = (float) min(min(newp[0].x,newp[1].x),min(newp[2].x,newp[3].x));
	float miny = (float) min(min(newp[0].y,newp[1].y),min(newp[2].y,newp[3].y));
	float maxx = (float) max(max(newp[0].x,newp[1].x),max(newp[2].x,newp[3].x));
	float maxy = (float) max(max(newp[0].y,newp[1].y),max(newp[2].y,newp[3].y));
	int newWidth = (int) floor(maxx-minx+0.5f);
	int newHeight= (int) floor(maxy-miny+0.5f);
	float ssx=((maxx+minx)- ((float) newWidth-1))/2.0f;   //start for x
	float ssy=((maxy+miny)- ((float) newHeight-1))/2.0f;  //start for y

	float newxcenteroffset = 0.5f * newWidth;
	float newycenteroffset = 0.5f * newHeight;
	if (bKeepOriginalSize){
		ssx -= 0.5f * GetWidth();
		ssy -= 0.5f * GetHeight();
	}

	//create destination image
	CxImage imgDest;
	imgDest.CopyInfo(*this);
	imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
	imgDest.SetPalette(GetPalette());
#if CXIMAGE_SUPPORT_ALPHA
	if(AlphaIsValid()) imgDest.AlphaCreate(); //MTA: Fix for rotation problem when the image has an alpha channel
#endif //CXIMAGE_SUPPORT_ALPHA
	
	RGBQUAD rgb;			//pixel colour
	RGBQUAD rc;
	if (replColor!=0) 
		rc=*replColor; 
	else {
		rc.rgbRed=255; rc.rgbGreen=255; rc.rgbBlue=255; rc.rgbReserved=0;
	}//if
	float x,y;              //destination location (float, with proper offset)
	float origx, origy;     //origin location
	int destx, desty;       //destination location
	
	y=ssy;                  //initialize y
	if (!IsIndexed()){ //RGB24
		//optimized RGB24 implementation (direct write to destination):
		BYTE *pxptr;
#if CXIMAGE_SUPPORT_ALPHA
		BYTE *pxptra=0;
#endif //CXIMAGE_SUPPORT_ALPHA
		for (desty=0; desty<newHeight; desty++) {
			info.nProgress = (long)(100*desty/newHeight);
			if (info.nEscape) break;
			//initialize x
			x=ssx;
			//calculate pointer to first byte in row
			pxptr=(BYTE *)imgDest.BlindGetPixelPointer(0, desty);
#if CXIMAGE_SUPPORT_ALPHA
			//calculate pointer to first byte in row
			if (AlphaIsValid()) pxptra=imgDest.AlphaGetPointer(0, desty);
#endif //CXIMAGE_SUPPORT_ALPHA
			for (destx=0; destx<newWidth; destx++) {
				//get source pixel coordinate for current destination point
				//origx = (cos_angle*(x-head.biWidth/2)+sin_angle*(y-head.biHeight/2))+newWidth/2;
				//origy = (cos_angle*(y-head.biHeight/2)-sin_angle*(x-head.biWidth/2))+newHeight/2;
				origx = cos_angle*x+sin_angle*y;
				origy = cos_angle*y-sin_angle*x;
				if (bKeepOriginalSize){
					origx += newxcenteroffset;
					origy += newycenteroffset;
				}
				rgb = GetPixelColorInterpolated(origx, origy, inMethod, ofMethod, &rc);   //get interpolated colour value
				//copy alpha and colour value to destination
#if CXIMAGE_SUPPORT_ALPHA
				if (pxptra) *pxptra++ = rgb.rgbReserved;
#endif //CXIMAGE_SUPPORT_ALPHA
				*pxptr++ = rgb.rgbBlue;
				*pxptr++ = rgb.rgbGreen;
				*pxptr++ = rgb.rgbRed;
				x++;
			}//for destx
			y++;
		}//for desty
	} else { 
		//non-optimized implementation for paletted images
		for (desty=0; desty<newHeight; desty++) {
			info.nProgress = (long)(100*desty/newHeight);
			if (info.nEscape) break;
			x=ssx;
			for (destx=0; destx<newWidth; destx++) {
				//get source pixel coordinate for current destination point
				origx=(cos_angle*x+sin_angle*y);
				origy=(cos_angle*y-sin_angle*x);
				if (bKeepOriginalSize){
					origx += newxcenteroffset;
					origy += newycenteroffset;
				}
				rgb = GetPixelColorInterpolated(origx, origy, inMethod, ofMethod, &rc);
				//***!*** SetPixelColor is slow for palleted images
#if CXIMAGE_SUPPORT_ALPHA
				if (AlphaIsValid()) 
					imgDest.SetPixelColor(destx,desty,rgb,true);
				else 
#endif //CXIMAGE_SUPPORT_ALPHA     
					imgDest.SetPixelColor(destx,desty,rgb,false);
				x++;
			}//for destx
			y++;
		}//for desty
	}
	//select the destination
	
	if (iDst) iDst->Transfer(imgDest);
	else Transfer(imgDest);
	
	return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Rotate180(CxImage* iDst)
{
	if (!pDib) return false;

	long wid = GetWidth();
	long ht = GetHeight();

	CxImage imgDest;
	imgDest.CopyInfo(*this);
	imgDest.Create(wid,ht,GetBpp(),GetType());
	imgDest.SetPalette(GetPalette());

#if CXIMAGE_SUPPORT_ALPHA
	if (AlphaIsValid())	imgDest.AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA

	long x,y,y2;
	for (y = 0; y < ht; y++){
		info.nProgress = (long)(100*y/ht); //<Anatoly Ivasyuk>
		y2=ht-y-1;
		for (x = 0; x < wid; x++){
			if(head.biClrUsed==0)//RGB
				imgDest.SetPixelColor(wid-x-1, y2, GetPixelColor(x, y));
			else  //PALETTE
				imgDest.SetPixelIndex(wid-x-1, y2, GetPixelIndex(x, y));

#if CXIMAGE_SUPPORT_ALPHA
			if (AlphaIsValid())	imgDest.AlphaSet(wid-x-1, y2,AlphaGet(x, y));
#endif //CXIMAGE_SUPPORT_ALPHA

		}
	}

	//select the destination
	if (iDst) iDst->Transfer(imgDest);
	else Transfer(imgDest);
	return true;
}

////////////////////////////////////////////////////////////////////////////////
/**
 * Resizes the image. mode can be 0 for slow (bilinear) method ,
 * 1 for fast (nearest pixel) method, or 2 for accurate (bicubic spline interpolation) method.
 * The function is faster with 24 and 1 bpp images, slow for 4 bpp images and slowest for 8 bpp images.
 */
bool CxImage::Resample(long newx, long newy, int mode, CxImage* iDst)
{
	if (newx==0 || newy==0) return false;

	if (head.biWidth==newx && head.biHeight==newy){
		if (iDst) iDst->Copy(*this);
		return true;
	}

	float xScale, yScale, fX, fY;
	xScale = (float)head.biWidth  / (float)newx;
	yScale = (float)head.biHeight / (float)newy;

	CxImage newImage;
	newImage.CopyInfo(*this);
	newImage.Create(newx,newy,head.biBitCount,GetType());
	newImage.SetPalette(GetPalette());
	if (!newImage.IsValid()) return false;

	switch (mode) {
	case 1: // nearest pixel
	{ 
		for(long y=0; y<newy; y++){
			info.nProgress = (long)(100*y/newy);
			if (info.nEscape) break;
			fY = y * yScale;
			for(long x=0; x<newx; x++){
				fX = x * xScale;
				newImage.SetPixelColor(x,y,GetPixelColor((long)fX,(long)fY));
			}
		}
		break;
	}
	case 2: // bicubic interpolation by Blake L. Carlson <blake-carlson(at)uiowa(dot)edu
	{
		float f_x, f_y, a, b, rr, gg, bb, r1, r2;
		int   i_x, i_y, xx, yy;
		RGBQUAD rgb;
		BYTE* iDst;
		for(long y=0; y<newy; y++){
			info.nProgress = (long)(100*y/newy);
			if (info.nEscape) break;
			f_y = (float) y * yScale - 0.5f;
			i_y = (int) floor(f_y);
			a   = f_y - (float)floor(f_y);
			for(long x=0; x<newx; x++){
				f_x = (float) x * xScale - 0.5f;
				i_x = (int) floor(f_x);
				b   = f_x - (float)floor(f_x);

				rr = gg = bb = 0.0f;
				for(int m=-1; m<3; m++) {
					r1 = KernelBSpline((float) m - a);
					yy = i_y+m;
					if (yy<0) yy=0;
					if (yy>=head.biHeight) yy = head.biHeight-1;
					for(int n=-1; n<3; n++) {
						r2 = r1 * KernelBSpline(b - (float)n);
						xx = i_x+n;
						if (xx<0) xx=0;
						if (xx>=head.biWidth) xx=head.biWidth-1;

						if (head.biClrUsed){
							rgb = GetPixelColor(xx,yy);
						} else {
							iDst  = info.pImage + yy*info.dwEffWidth + xx*3;
							rgb.rgbBlue = *iDst++;
							rgb.rgbGreen= *iDst++;
							rgb.rgbRed  = *iDst;
						}

						rr += rgb.rgbRed * r2;
						gg += rgb.rgbGreen * r2;
						bb += rgb.rgbBlue * r2;
					}
				}

				if (head.biClrUsed)
					newImage.SetPixelColor(x,y,RGB(rr,gg,bb));
				else {
					iDst = newImage.info.pImage + y*newImage.info.dwEffWidth + x*3;
					*iDst++ = (BYTE)bb;
					*iDst++ = (BYTE)gg;
					*iDst   = (BYTE)rr;
				}

			}
		}
		break;
	}
	default: // bilinear interpolation
		if (!(head.biWidth>newx && head.biHeight>newy && head.biBitCount==24)) {
			//

⌨️ 快捷键说明

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