📄 ximasel.cpp
字号:
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: petter.holmberg@usa.net 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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()) return false;
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.SetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
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] == 255){
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 + -