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

📄 ximasel.cpp

📁 对CFileException进行修改后 这个血管提取的程序已经可以在VC8下面编译了 但是还有点内存泄露 没有进行修正 等有时间了在进行修改
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// xImaSel.cpp : Selection functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
 * CxImage version 5.99c 17/Oct/2004
 */

#include "ximage.h"

#if CXIMAGE_SUPPORT_SELECTION

////////////////////////////////////////////////////////////////////////////////
/**
 * Checks if the image has a valid selection.
 */
bool CxImage::SelectionIsValid()
{
	return pSelection!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Gets the smallest rectangle that contains the selection 
 */
void CxImage::SelectionGetBox(RECT& r)
{
	memcpy(&r,&info.rSelectionBox,sizeof(RECT));
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Empties the selection.
 */
bool CxImage::SelectionClear()
{
	if (pSelection){
		memset(pSelection,0,head.biWidth * head.biHeight);
		info.rSelectionBox.left = head.biWidth;
		info.rSelectionBox.bottom = head.biHeight;
		info.rSelectionBox.right = info.rSelectionBox.top = 0;
		return true;
	}
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Allocates an empty selection.
 */
bool CxImage::SelectionCreate()
{
	SelectionDelete();
	pSelection = (BYTE*)calloc(head.biWidth * head.biHeight, 1);
	return (pSelection!=0);
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Deallocates the selction.
 */
bool CxImage::SelectionDelete()
{
	if (pSelection){ free(pSelection); pSelection=NULL; }
	info.rSelectionBox.left = head.biWidth;
	info.rSelectionBox.bottom = head.biHeight;
	info.rSelectionBox.right = info.rSelectionBox.top = 0;
	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Checks if the coordinates are inside the selection.
 */
bool CxImage::SelectionIsInside(long x, long y)
{
	if (IsInside(x,y)){
		if (pSelection==NULL) return true;
		return pSelection[x+y*head.biWidth]!=0;
	}
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Adds a rectangle to the existing selection.
 */
bool CxImage::SelectionAddRect(RECT r)
{
	if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	RECT r2;
	if (r.left<r.right) {r2.left=r.left; r2.right=r.right; } else {r2.left=r.right ; r2.right=r.left; }
	if (r.bottom<r.top) {r2.bottom=r.bottom; r2.top=r.top; } else {r2.bottom=r.top ; r2.top=r.bottom; }

	if (info.rSelectionBox.top < r2.top) info.rSelectionBox.top = max(0L,min(head.biHeight,r2.top));
	if (info.rSelectionBox.left > r2.left) info.rSelectionBox.left = max(0L,min(head.biWidth,r2.left));
	if (info.rSelectionBox.right < r2.right) info.rSelectionBox.right = max(0L,min(head.biWidth,r2.right));
	if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom));

	long ymin = max(0L,min(head.biHeight,r2.bottom));
	long ymax = max(0L,min(head.biHeight,r2.top));
	long xmin = max(0L,min(head.biWidth,r2.left));
	long xmax = max(0L,min(head.biWidth,r2.right));

	for (long y=ymin; y<ymax; y++)
		memset(pSelection + xmin + y * head.biWidth, 255, xmax-xmin);

	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Adds an ellipse to the existing selection.
 */
bool CxImage::SelectionAddEllipse(RECT r)
{
	if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	long xradius = abs(r.right - r.left)/2;
	long yradius = abs(r.top - r.bottom)/2;
	if (xradius==0 || yradius==0) return false;

	long xcenter = (r.right + r.left)/2;
	long ycenter = (r.top + r.bottom)/2;

	if (info.rSelectionBox.left > (xcenter - xradius)) info.rSelectionBox.left = max(0L,min(head.biWidth,(xcenter - xradius)));
	if (info.rSelectionBox.right < (xcenter + xradius)) info.rSelectionBox.right = max(0L,min(head.biWidth,(xcenter + xradius)));
	if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = max(0L,min(head.biHeight,(ycenter - yradius)));
	if (info.rSelectionBox.top < (ycenter + yradius)) info.rSelectionBox.top = max(0L,min(head.biHeight,(ycenter + yradius)));

	long xmin = max(0L,min(head.biWidth,xcenter - xradius));
	long xmax = max(0L,min(head.biWidth,xcenter + xradius));
	long ymin = max(0L,min(head.biHeight,ycenter - yradius));
	long ymax = max(0L,min(head.biHeight,ycenter + yradius));

	long y,yo;
	for (y=ymin; y<ycenter; y++){
		for (long x=xmin; x<xmax; x++){
			yo = (long)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
			if (yo<y) pSelection[x + y * head.biWidth] = 255;
		}
	}
	for (y=ycenter; y<ymax; y++){
		for (long x=xmin; x<xmax; x++){
			yo = (long)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
			if (yo>y) pSelection[x + y * head.biWidth] = 255;
		}
	}
	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Inverts the selection.
 */
bool CxImage::SelectionInvert()
{
	if (pSelection) {
		BYTE *iSrc=pSelection;
		long n=head.biHeight*head.biWidth;
		for(long i=0; i < n; i++){
			*iSrc=(BYTE)~(*(iSrc));
			iSrc++;
		}
		return true;
	}
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Imports an existing region from another image with the same width and height.
 */
bool CxImage::SelectionCopy(CxImage &from)
{
	if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
	if (pSelection==NULL) pSelection = (BYTE*)malloc(head.biWidth * head.biHeight);
	if (pSelection==NULL) return false;
	memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight);
	memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT));
	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Adds a polygonal region to the existing selection. points points to an array of POINT structures.
 * Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon.
 * npoints specifies the number of POINT structures in the array pointed to by points.
 */
bool CxImage::SelectionAddPolygon(POINT *points, long npoints)
{
	if (points==NULL || npoints<3) return false;

	if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	BYTE* plocal = (BYTE*)calloc(head.biWidth*head.biHeight, 1);
	RECT localbox = {head.biWidth,0,0,head.biHeight};

	long x,y,i=0;
	POINT *current,*next,*start;
	//trace contour
	while (i < npoints){
		current = &points[i];
		if (current->x!=-1){
			if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i];

			if ((i+1)==npoints || points[i+1].x==-1)
				next = start;
			else
				next = &points[i+1];

			float beta;
			if (current->x != next->x){
				beta = (float)(next->y - current->y)/(float)(next->x - current->x);
				if (current->x < next->x){
					for (x=current->x; x<=next->x; x++){
						y = (long)(current->y + (x - current->x) * beta);
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
					}
				} else {
					for (x=current->x; x>=next->x; x--){
						y = (long)(current->y + (x - current->x) * beta);
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
					}
				}
			}
			if (current->y != next->y){
				beta = (float)(next->x - current->x)/(float)(next->y - current->y);
				if (current->y < next->y){
					for (y=current->y; y<=next->y; y++){
						x = (long)(current->x + (y - current->y) * beta);
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
					}
				} else {
					for (y=current->y; y>=next->y; y--){
						x = (long)(current->x + (y - current->y) * beta);
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
					}
				}
			}
		}

		RECT r2;
		if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; }

⌨️ 快捷键说明

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