📄 cellview.cpp
字号:
g_pFlags[INDEX(i, j)].marked=0;
}
}
GenEdge();
InvalidateRect(0,TRUE);
}
}
else if (m_bForceAdd)
{
if(m_SelectedRect.left >= m_SelectedRect.right || m_SelectedRect.top >= m_SelectedRect.bottom)
MessageBox("选择的范围不正确.请重新选择!");
else
{
m_bForceAdd = false;
m_SelectedRect.left+=scroll_lefttop.x;
m_SelectedRect.right+=scroll_lefttop.x;
m_SelectedRect.top+=scroll_lefttop.y;
m_SelectedRect.bottom+=scroll_lefttop.y;
for(int j = m_SelectedRect.top; j < m_SelectedRect.bottom; j++)
{
for(int i = m_SelectedRect.left; i < m_SelectedRect.right; i++)
{
if (i<0 || i>=g_nMapWidth || j<0 || j>=g_nMapHeight)
continue;
g_pFlags[INDEX(i, j)].marked=1;
}
}
GenEdge();
InvalidateRect(0,TRUE);
}
}
}
CView::OnLButtonUp(nFlags, point);
}
bool CCellView::LoadImageBuffer(HDC memdc,char *szFileName)
{
BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER bitmapinfoheader;
BITMAPINFO bitmapinfo;
// this function opens a bitmap file and loads the data into bitmap
int file_handle; // the file handle
OFSTRUCT file_data; // the file data information
// open the file if it exists
if ((file_handle = OpenFile(szFileName,&file_data,OF_READ))==-1)
return 0;
// now load the bitmap file header
_lread(file_handle, &bitmapfileheader,sizeof(BITMAPFILEHEADER));
// test if this is a bitmap file
if (bitmapfileheader.bfType!=BITMAP_ID)
{
// close the file
_lclose(file_handle);
// return error
return 0;
} // end if
// now we know this is a bitmap, so read in all the sections
// first the bitmap infoheader
// now load the bitmap file header
_lread(file_handle, &bitmapinfoheader, sizeof(BITMAPINFOHEADER));
if (bitmapinfoheader.biWidth%4 != 0) // 宽度不是4的倍数
{
MessageBox("文件宽度不是4的倍数");
_lclose(file_handle);
return 0;
}
if(g_pImgBuffer) // clear it if not null
delete[] g_pImgBuffer;
g_pImgBuffer = new RGB[g_nMapHeight * g_nMapWidth]; // make space
// 申请备份buffer空间
// if (g_pImgBufferBack)
// delete[] g_pImgBufferBack;
// g_pImgBufferBack=new RGB[g_nMapHeight * g_nMapWidth];
// if (g_pOrgImgBuffer)
// delete[] g_pOrgImgBuffer;
// g_pOrgImgBuffer=new RGB[g_nMapHeight * g_nMapWidth];
// now load the color palette if there is one
if (bitmapinfoheader.biBitCount != 24)
{
// set bitmapinfo
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfo.bmiHeader.biWidth = g_nMapWidth;
bitmapinfo.bmiHeader.biHeight = g_nMapHeight;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 24;
bitmapinfo.bmiHeader.biCompression = BI_RGB;
GetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, NULL,
&bitmapinfo, DIB_RGB_COLORS);
GetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, g_pImgBuffer,
&bitmapinfo, DIB_RGB_COLORS);
}
else
{
_llseek(file_handle, bitmapfileheader.bfOffBits,FILE_BEGIN);
_lread(file_handle, g_pImgBuffer, 3*g_nMapHeight*g_nMapWidth);
}
FlipBitmapData(g_pImgBuffer);
// memcpy(g_pOrgImgBuffer,g_pImgBuffer,sizeof(RGB)*g_nMapWidth*g_nMapHeight);
// close the file
_lclose(file_handle);
// return success
return 1;
}
void CCellView::FlipBitmapData(RGB *buffer)
{
RGB *tempmem;
int bytes_per_line=g_nMapWidth*sizeof(RGB);
tempmem=new RGB[g_nMapWidth*g_nMapHeight];
memcpy(tempmem,buffer,bytes_per_line*g_nMapHeight);
for (int i=0;i<g_nMapHeight;i++)
memcpy(&buffer[((g_nMapHeight-1) - i)*g_nMapWidth],
&tempmem[i*g_nMapWidth], bytes_per_line);
delete[] tempmem;
}
void CCellView::OnProcHsi()
{
if(g_hBitmap)
{
m_bProcHsi = true;
MessageBox("请选择一块小区域作为颜色选取范围");
}
else
MessageBox("请先打开图像文件!");
}
BOOL CCellView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(m_bProcHsi || m_bForceKill || m_bForceAdd)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
return TRUE;
}
void CCellView::ProcHSI(bool bEx)
{
m_vHSI.clear();
// fill vector
HSI *hsi;
huegap=256.0*g_nHueGap/100.0;
if (huegap>5.12)
huegap=5.12;
huegap+=0.0001;
intgap=g_nIntGap/100.0;
if (intgap>0.02)
intgap=0.02;
intgap+=0.0001;
satgap=g_nSatGap/100.0;
if (satgap>0.02)
satgap=0.02;
satgap+=0.0001;
m_SelectedRect.left+=scroll_lefttop.x;
m_SelectedRect.right+=scroll_lefttop.x;
m_SelectedRect.top+=scroll_lefttop.y;
m_SelectedRect.bottom+=scroll_lefttop.y;
for(int j = m_SelectedRect.top; j < m_SelectedRect.bottom; j++)
{
for(int i = m_SelectedRect.left; i < m_SelectedRect.right; i++)
{
if (i<0 || i>=g_nMapWidth || j<0 || j>=g_nMapHeight)
continue;
if(!g_pFlags[INDEX(i, j)].marked)
{
hsi=&g_pHSIBuffer[INDEX(i,j)];
if(FindInVectorHSI(m_vHSI, *hsi) == false)
{
m_vHSI.push_back(*hsi);
m_vAllSelected.push_back(*hsi);
}
}
}
}
if(m_vHSI.size())
{
// backup
// memcpy(g_pImgBufferBack,g_pImgBuffer,
// sizeof(RGB)*g_nMapWidth*g_nMapHeight);
memcpy(g_pFlagsBack,g_pFlags,
sizeof(FLAGS)*g_nMapWidth*g_nMapHeight);
// g_bImgBufferChanged=true;
HsiProcess(bEx);
// m_vHSI.clear();
GenEdge();
InvalidateRect(0, TRUE);
}
}
void CCellView::GenHSIData()
{
int wd, ht;
HSI tmp;
RGB *cur;
if(g_pHSIBuffer)
delete[] g_pHSIBuffer;
g_pHSIBuffer = new HSI[g_nMapWidth * g_nMapHeight];
memset(g_pHSIBuffer, 0, sizeof(HSI) * g_nMapWidth * g_nMapHeight);
HSI *pHueBuffer = g_pHSIBuffer;
cur = g_pImgBuffer;
for(ht = 0; ht < g_nMapHeight; ht++)
{
for(wd = 0; wd < g_nMapWidth; wd++)
{
RgbToHsi(cur, &tmp);
pHueBuffer->Hue = tmp.Hue*255.0/360.0;
pHueBuffer->Intensity = tmp.Intensity;
pHueBuffer->Saturation = tmp.Saturation;
pHueBuffer++;
cur++;
}
}
}
bool CCellView::FindInVectorHSI(vector<HSI> v, HSI c)
{
int size = v.size();
for(int i = 0; i < size; i++)
// if(c.Hue == v.at(i).Hue && c.Intensity == v.at(i).Intensity && c.Saturation == v.at(i).Saturation)
if( fabs(c.Hue - v.at(i).Hue) < huegap &&
fabs(c.Intensity - v.at(i).Intensity) < intgap &&
fabs(c.Saturation - v.at(i).Saturation) < satgap )
return true;
return false;
}
void CCellView::HsiProcess(bool bEx)
{
RGB *cur=g_pImgBuffer;
HSI *pHSI=g_pHSIBuffer;
int size = m_vHSI.size();
double sH, sS, sI, dH, dS, dI;
HSI tmp, vtmp;
int ht, wd;
FLAGS *cur_flag = g_pFlags; // flag
for(ht = 0; ht < g_nMapHeight; ht++)
{
for(wd = 0; wd < g_nMapWidth; wd++)
{
if(cur_flag->marked)
{
cur++;
cur_flag++; // flag
pHSI++;
continue;
}
memcpy(&tmp,pHSI,sizeof(HSI));
pHSI++;
for(int i = 0; i < size; i++)
{
vtmp = m_vHSI.at(i);
sH = vtmp.Hue;
sS = vtmp.Saturation;
sI = vtmp.Intensity;
dH = tmp.Hue;
dS = tmp.Saturation;
dI = tmp.Intensity;
if(!bEx) // 排除法
{
if
(
sH - dH >= 0 - g_nHueGap * 2.55
&& sH - dH <= g_nHueGap * 2.55
&& sS - dS >= 0 - g_nSatGap / 100.0
&& sS - dS <= g_nSatGap / 100.0
&& sI - dI >= 0 - g_nIntGap / 100.0
&& sI - dI <= g_nIntGap / 100.0
)
{
cur_flag->marked = 1; // set marked
// cur->r=cur->g=cur->b=0;
continue;
}
}
else
{
if
(
(sH - dH <= 0 - g_nHueGap * 2.55 || sH - dH >= g_nHueGap * 2.55)
&& (sS - dS <= 0 - g_nSatGap / 100.0 || sS - dS >= g_nSatGap / 100.0)
&& (sI - dI <= 0 - g_nIntGap / 100.0 || sI - dI >= g_nIntGap / 100.0)
)
{
cur_flag->marked = 1; // set marked
cur->r=cur->g=cur->b=0;
continue;
}
}
}
cur++;
cur_flag++; // flag
}
}
}
void CCellView::OnEditUndo()
{
// TODO: Add your command handler code here
// RGB *exch;
FLAGS *exchf;
if (g_pFlagsBack)
{
// exch=g_pImgBufferBack;
// g_pImgBufferBack=g_pImgBuffer;
// g_pImgBuffer=exch;
// g_bImgBufferChanged=true;
// 恢复
if(g_pFlags && g_pFlagsBack)
{
exchf=g_pFlags;
g_pFlags=g_pFlagsBack;
g_pFlagsBack=exchf;
}
InvalidateRect(NULL,TRUE);
}
}
void CCellView::OnProcSobel()
{
if(!g_hBitmap)
MessageBox("请先打开文件");
else // here we go~
{
double SobelTemplateGx[9];
double SobelTemplateGy[9];
// -1 -2 -1
// 0 0 0
// 1 2 1
SobelTemplateGx[0] = -1;
SobelTemplateGx[1] = -2;
SobelTemplateGx[2] = -1;
SobelTemplateGx[3] = 0;
SobelTemplateGx[4] = 0;
SobelTemplateGx[5] = 0;
SobelTemplateGx[6] = 1;
SobelTemplateGx[7] = 2;
SobelTemplateGx[8] = 1;
// -1 0 1
// -2 0 2
// -1 0 1
SobelTemplateGy[0] = -1;
SobelTemplateGy[1] = 0;
SobelTemplateGy[2] = 1;
SobelTemplateGy[3] = -2;
SobelTemplateGy[4] = 0;
SobelTemplateGy[5] = 2;
SobelTemplateGy[6] = -1;
SobelTemplateGy[7] = 0;
SobelTemplateGy[8] = 1;
if(g_pSobelResult)
delete[] g_pSobelResult;
g_pSobelResult = new BYTE[g_nMapWidth * g_nMapHeight];
if(!g_pSobelResult)
{
MessageBox("not enough memory");
return;
}
RGB *got;
double tempr, tempg, tempb;
double multi;
double result;
int x, y;
BYTE *cur_pos=g_pSobelResult;
for(y = 0; y < g_nMapHeight; y++)
{
for(x = 0; x < g_nMapWidth; x++)
{
// 计算Gx方向
tempr = tempg = tempb = 0;
got = GetBit(x - 1, y - 1);
if(got)
{
multi = SobelTemplateGx[0];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x, y - 1);
if(got)
{
multi = SobelTemplateGx[1];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x + 1, y - 1);
if(got)
{
multi = SobelTemplateGx[2];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x - 1, y);
if(got)
{
multi = SobelTemplateGx[3];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x, y);
if(got)
{
multi = SobelTemplateGx[4];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x + 1, y);
if(got)
{
multi = SobelTemplateGx[5];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x - 1, y + 1);
if(got)
{
multi = SobelTemplateGx[6];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x, y + 1);
if(got)
{
multi = SobelTemplateGx[7];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x + 1, y + 1);
if(got)
{
multi = SobelTemplateGx[8];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
result = fabs(tempr) + fabs(tempg) + fabs(tempb);
// 计算Gy方向
tempr = tempg = tempb = 0;
got = GetBit(x - 1, y - 1);
if(got)
{
multi = SobelTemplateGy[0];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x, y - 1);
if(got)
{
multi = SobelTemplateGy[1];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x + 1, y - 1);
if(got)
{
multi = SobelTemplateGy[2];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x - 1, y);
if(got)
{
multi = SobelTemplateGy[3];
tempr += multi * got->r;
tempg += multi * got->g;
tempb += multi * got->b;
}
got = GetBit(x, y);
if(got)
{
multi = SobelTemplateGy[4];
tempr += multi * got->r;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -