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

📄 ximasel.cpp

📁 用Cximage 库显示各种格式图片小程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
							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--;
						}
						
						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]=level;
	}
	if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = min(head.biHeight,localbox.top + 1);
	if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = min(head.biWidth,localbox.left);
	if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = min(head.biWidth,localbox.right + 1);
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = min(head.biHeight,localbox.bottom);

	free(plocal);
	free(pix);

	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Adds to the selection all the pixels matching the specified color.
 */
bool CxImage::SelectionAddColor(RGBQUAD c, BYTE level)
{
    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 = 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Adds a single pixel to the existing selection.
 */
bool CxImage::SelectionAddPixel(long x, long y, BYTE 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Exports the selection channel in a 8bpp grayscale image.
 */
bool CxImage::SelectionSplit(CxImage *dest)
{
	if (!pSelection || !dest) return false;

	CxImage tmp(head.biWidth,head.biHeight,8);
	if (!tmp.IsValid()){
		strcpy(info.szLastError,tmp.GetLastError());
		return false;
	}

	for(long y=0; y<head.biHeight; y++){
		for(long x=0; x<head.biWidth; x++){
			tmp.BlindSetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
		}
	}

	tmp.SetGrayPalette();
	dest->Transfer(tmp);

	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Creates the selection channel from a gray scale image.
 * black = unselected
 */
bool CxImage::SelectionSet(CxImage &from)
{
	if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight){
		strcpy(info.szLastError,"CxImage::SelectionSet: wrong width or height, or image is not gray scale");
		return false;
	}

	if (pSelection==NULL) pSelection = (BYTE*)malloc(head.biWidth * head.biHeight);

	BYTE* src = from.info.pImage;
	BYTE* dst = pSelection;
	if (src==NULL || dst==NULL){
		strcpy(info.szLastError,"CxImage::SelectionSet: null pointer");
		return false;
	}

	for (long y=0; y<head.biHeight; y++){
		memcpy(dst,src,head.biWidth);
		dst += head.biWidth;
		src += from.info.dwEffWidth;
	}

	SelectionRebuildBox();

	return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Sets the Selection level for a single pixel
 * internal use only: doesn't set SelectionBox. Use SelectionAddPixel
 */
void CxImage::SelectionSet(const long x,const long y,const BYTE level)
{
	if (pSelection && IsInside(x,y)) pSelection[x+y*head.biWidth]=level;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Gets the Selection level for a single pixel 
 */
BYTE CxImage::SelectionGet(const long x,const long y)
{
	if (pSelection && IsInside(x,y)) return pSelection[x+y*head.biWidth];
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Rebuilds the SelectionBox 
 */
void CxImage::SelectionRebuildBox()
{
	info.rSelectionBox.left = head.biWidth;
	info.rSelectionBox.bottom = head.biHeight;
	info.rSelectionBox.right = info.rSelectionBox.top = 0;

	if (!pSelection)
		return;

	long x,y;

	for (y=0; y<head.biHeight; y++){
		for (x=0; x<info.rSelectionBox.left; x++){
			if (pSelection[x+y*head.biWidth]){
				info.rSelectionBox.left = x;
				continue;
			}
		}
	}

	for (y=0; y<head.biHeight; y++){
		for (x=head.biWidth-1; x>=info.rSelectionBox.right; x--){
			if (pSelection[x+y*head.biWidth]){
				info.rSelectionBox.right = x+1;
				continue;
			}
		}
	}

	for (x=0; x<head.biWidth; x++){
		for (y=0; y<info.rSelectionBox.bottom; y++){
			if (pSelection[x+y*head.biWidth]){
				info.rSelectionBox.bottom = y;
				continue;
			}
		}
	}

	for (x=0; x<head.biWidth; x++){
		for (y=head.biHeight-1; y>=info.rSelectionBox.top; y--){
			if (pSelection[x+y*head.biWidth]){
				info.rSelectionBox.top = y+1;
				continue;
			}
		}
	}

}
////////////////////////////////////////////////////////////////////////////////
/**
 * Gets the Selection level for a single pixel 
 * "blind" version assumes that (x,y) is inside to the image.
 */
BYTE CxImage::BlindSelectionGet(const long x,const long y)
{
#ifdef _DEBUG
	if (!IsInside(x,y) || (pSelection==0))
  #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
		throw 0;
  #else
		return 0;
  #endif
#endif
	return pSelection[x+y*head.biWidth];
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Returns pointer to selection data for pixel (x,y).
 */
BYTE* CxImage::SelectionGetPointer(const long x,const long y)
{
	if (pSelection && IsInside(x,y)) return pSelection+x+y*head.biWidth;
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::SelectionFlip()
{
	if (!pSelection) return false;

	BYTE *buff = (BYTE*)malloc(head.biWidth);
	if (!buff) return false;

	BYTE *iSrc,*iDst;
	iSrc = pSelection + (head.biHeight-1)*head.biWidth;
	iDst = pSelection;
	for (long i=0; i<(head.biHeight/2); ++i)
	{
		memcpy(buff, iSrc, head.biWidth);
		memcpy(iSrc, iDst, head.biWidth);
		memcpy(iDst, buff, head.biWidth);
		iSrc-=head.biWidth;
		iDst+=head.biWidth;
	}

	free(buff);

	long top = info.rSelectionBox.top;
	info.rSelectionBox.top = head.biHeight - info.rSelectionBox.bottom;
	info.rSelectionBox.bottom = head.biHeight - top;
	return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::SelectionMirror()
{
	if (!pSelection) return false;
	BYTE* pSelection2 = (BYTE*)malloc(head.biWidth * head.biHeight);
	if (!pSelection2) return false;
	
	BYTE *iSrc,*iDst;
	long wdt=head.biWidth-1;
	iSrc=pSelection + wdt;
	iDst=pSelection2;
	for(long y=0; y < head.biHeight; y++){
		for(long x=0; x <= wdt; x++)
			*(iDst+x)=*(iSrc-x);
		iSrc+=head.biWidth;
		iDst+=head.biWidth;
	}
	free(pSelection);
	pSelection=pSelection2;
	
	long left = info.rSelectionBox.left;
	info.rSelectionBox.left = head.biWidth - info.rSelectionBox.right;
	info.rSelectionBox.right = head.biWidth - left;
	return true;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINDOWS
/**
 * Converts the selection in a HRGN object.
 */
bool CxImage::SelectionToHRGN(HRGN& region)
{
	if (pSelection && region){           
        for(int y = 0; y < head.biHeight; y++){
            HRGN hTemp = NULL;
            int iStart = -1;
            int x = 0;
			for(; x < head.biWidth; x++){
                if (pSelection[x + y * head.biWidth] != 0){
					if (iStart == -1) iStart = x;
					continue;
                }else{
                    if (iStart >= 0){
                        hTemp = CreateRectRgn(iStart, y, x, y + 1);
                        CombineRgn(region, hTemp, region, RGN_OR);
                        DeleteObject(hTemp);
                        iStart = -1;
                    }
                }
            }
            if (iStart >= 0){
                hTemp = CreateRectRgn(iStart, y, x, y + 1);
                CombineRgn(region, hTemp, region, RGN_OR);
                DeleteObject(hTemp);
                iStart = -1;
            }
        }
		return true;
    }
	return false;
}
#endif //CXIMAGE_SUPPORT_WINDOWS
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_SELECTION

⌨️ 快捷键说明

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