示例#1
0
/**
 * Adds to the selection all the pixels matching the specified color.
 */
bool CxImage::SelectionAddColor(RGBQUAD c, uint8_t level)
{
    if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	RECT localbox = {head.biWidth,0,0,head.biHeight};

    for (int32_t y = 0; y < head.biHeight; y++){
        for (int32_t x = 0; x < head.biWidth; x++){
            RGBQUAD color = BlindGetPixelColor(x, y);
            if (color.rgbRed   == c.rgbRed &&
				color.rgbGreen == c.rgbGreen &&
                color.rgbBlue  == c.rgbBlue)
            {
                pSelection[x + y * head.biWidth] = level;

				if (localbox.top < y) localbox.top = y;
				if (localbox.left > x) localbox.left = x;
				if (localbox.right < x) localbox.right = x;
				if (localbox.bottom > y) localbox.bottom = y;
            }
        }
    }

	if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1;
	if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
	if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1;
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;

	return true;
}
示例#2
0
/**
 * Adds to the selection all the pixels matching the specified color.
 */
bool CxImage::SelectionAddColor(RGBQUAD c)
{
    if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	RECT localbox = {head.biWidth,0,0,head.biHeight};

    for (long y = 0; y < head.biHeight; y++){
        for (long x = 0; x < head.biWidth; x++){
            RGBQUAD color = GetPixelColor(x, y);
            if (color.rgbRed   == c.rgbRed &&
				color.rgbGreen == c.rgbGreen &&
                color.rgbBlue  == c.rgbBlue)
            {
                pSelection[x + y * head.biWidth] = 255; // set the correct mask bit

				if (localbox.top < y) localbox.top = y;
				if (localbox.left > x) localbox.left = x;
				if (localbox.right < x) localbox.right = x;
				if (localbox.bottom > y) localbox.bottom = y;
            }
        }
    }

	if (info.rSelectionBox.top < localbox.top) info.rSelectionBox.top = localbox.top;
	if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
	if (info.rSelectionBox.right < localbox.right) info.rSelectionBox.right = localbox.right;
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;

	return true;
}
示例#3
0
/**
 * Adds a single pixel to the existing selection.
 */
bool CxImage::SelectionAddPixel(int x, int y)
{
    if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

    if (IsInside(x,y)) {
        pSelection[x + y * head.biWidth] = 255; // set the correct mask bit
        return true;
    }

    return false;
}
示例#4
0
/**
 * Adds a single pixel to the existing selection.
 */
bool CxImage::SelectionAddPixel(int32_t x, int32_t y, uint8_t level)
{
    if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

    if (IsInside(x,y)) {
        pSelection[x + y * head.biWidth] = level; // set the correct mask bit

		if (info.rSelectionBox.top <= y) info.rSelectionBox.top = y+1;
		if (info.rSelectionBox.left > x) info.rSelectionBox.left = x;
		if (info.rSelectionBox.right <= x) info.rSelectionBox.right = x+1;
		if (info.rSelectionBox.bottom > y) info.rSelectionBox.bottom = y;

        return true;
    }

    return false;
}
示例#5
0
/**
 * 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;
}
示例#6
0
/**
 * Adds an ellipse to the existing selection.
 */
bool CxImage::SelectionAddEllipse(RECT r, uint8_t level)
{
	if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

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

	int32_t xcenter = (r.right + r.left)/2;
	int32_t 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 + 1)));
	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 + 1)));

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

	int32_t y,yo;
	for (y=ymin; y<min(ycenter,ymax); y++){
		for (int32_t x=xmin; x<xmax; x++){
			yo = (int32_t)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
			if (yo<y) pSelection[x + y * head.biWidth] = level;
		}
	}
	for (y=ycenter; y<ymax; y++){
		for (int32_t x=xmin; x<xmax; x++){
			yo = (int32_t)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
			if (yo>y) pSelection[x + y * head.biWidth] = level;
		}
	}
	return true;
}
示例#7
0
/**
 * 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;
}
示例#8
0
	/**
	 * Adds a rectangle to the existing selection.
	 */
	bool CxImage::SelectionAddRect(Rect r, uint8_t level)
	{
		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(0,min(head.biHeight,r2.top+1));
		if (info.rSelectionBox.left > r2.left) info.rSelectionBox.left = max(0,min(head.biWidth,r2.left));
		if (info.rSelectionBox.right <= r2.right) info.rSelectionBox.right = max(0,min(head.biWidth,r2.right+1));
		if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0,min(head.biHeight,r2.bottom));

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

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

		return true;
	}
示例#9
0
/**
 * 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; }
		if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; }
		if (localbox.top < r2.top) localbox.top = max(0L,min(head.biHeight-1,r2.top+1));
		if (localbox.left > r2.left) localbox.left = max(0L,min(head.biWidth-1,r2.left-1));
		if (localbox.right < r2.right) localbox.right = max(0L,min(head.biWidth-1,r2.right+1));
		if (localbox.bottom > r2.bottom) localbox.bottom = max(0L,min(head.biHeight-1,r2.bottom-1));

		i++;
	}

	//fill the outer region
	long npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom);
	POINT* pix = (POINT*)calloc(npix,sizeof(POINT));
	BYTE back=0, mark=1;
	long fx, fy, fxx, fyy, first, last,xmin,xmax,ymin,ymax;

	for (int side=0; side<4; side++){
		switch(side){
		case 0:
			xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.bottom+1;
			break;
		case 1:
			xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top+1;
			break;
		case 2:
			xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.top; ymax=localbox.top+1;
			break;
		case 3:
			xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top+1;
			break;
		}
		//fill from the border points
		for(y=ymin;y<ymax;y++){
			for(x=xmin;x<xmax;x++){
				if (plocal[x+y*head.biWidth]==0){
					// Subject: FLOOD FILL ROUTINE              Date: 12-23-97 (00:57)       
					// Author:  Petter Holmberg                 Code: QB, QBasic, PDS        
					// Origin:  [email protected]         Packet: GRAPHICS.ABC
					first=0;
					last=1;
					while(first!=last){
						fx = pix[first].x;
						fy = pix[first].y;
						fxx = fx + x;
						fyy = fy + y;
						do {
							if ((plocal[fxx + fyy*head.biWidth] == back) &&
								fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
							{
								plocal[fxx + fyy*head.biWidth] = mark;
								if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
									pix[last].x = fx;
									pix[last].y = fy - 1;
									last++;
									if (last == npix) last = 0;
								}
								if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
									pix[last].x = fx;
									pix[last].y = fy + 1;
									last++;
									if (last == npix) last = 0;
								}
							} else {
								break;
							}
							fx++;
							fxx++;
						} while(1);

						fx = pix[first].x - 1;
						fy = pix[first].y;
						fxx = fx + x;
						fyy = fy + y;

						do {
							if ((plocal[fxx + fyy*head.biWidth] == back) &&
								fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
							{
								plocal[fxx + (y + fy)*head.biWidth] = mark;
								if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
									pix[last].x = fx;
									pix[last].y = fy - 1;
									last++;
									if (last == npix) last = 0;
								}
								if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
									pix[last].x = fx;
									pix[last].y = fy + 1;
									last++;
									if (last == npix) last = 0;
								}
							} else {
								break;
							}
							fx--;
							fxx--;
						} while(1);
						
						first++;
						if (first == npix) first = 0;
					}
				}
			}
		}
	}

	//transfer the region
	long yoffset;
	for (y=localbox.bottom; y<=localbox.top; y++){
		yoffset = y * head.biWidth;
		for (x=localbox.left; x<=localbox.right; x++)
			if (plocal[x + yoffset]!=1) pSelection[x + yoffset]=255;
	}
	if (info.rSelectionBox.top < localbox.top) info.rSelectionBox.top = localbox.top+1;
	if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
	if (info.rSelectionBox.right < localbox.right) info.rSelectionBox.right = localbox.right+1;
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;

	free(plocal);
	free(pix);

	return true;
}