|
성호님 제가 능력이 부족해서 이해를 못하고 있습니다
제가 소스를 아무리 바도 사각형 위치를 찾는 방법을 도저히 모르겠습니다
제가 그림으로 올렷는데요 빨간줄이 읽는 거구 파란줄이 직사각형을 찾는 방법인거 같은데
이것이 맞는지요? 맞는 다면 어떻게 사각형 위치를 잡는거죠???
두번째 그림은 마우스로 일정영역을 잡아서 상하 좌우를 검사해서 하는건 성공했는데
전체를 검사하는 방법을 몰라서 이렇게 질문이 하게 되겁니다 ㅜ_ㅜ 이건 질문이 아니라 푸념 ㅜ_ㅜ
장성호 님이 쓰신 글 :
: [ bmp 파일 포멧에 대해]
:
: BMP 파일을 Hex Editer로 열어보면 실제 데이타는
: 이미지의 맨 끝에 라인부터 파일에 기록되어 있습니다.
:
: Graphics::TBitmap 에서 ScanLine을 이용해 Data의 Pointer를 가져오는데
: 중요한것은
: ScanLine(0) 에서 Width 만큼 Pointer를 증가하면 ScanLine(1) 이 아니구
: 실제로는 그 반대로 되어있습니다.
:
: 첫번째 줄 ScanLine(0) 에서 다음줄로 가려면 포인터를 Width 만큼 더해주는것이 아니라 빼줘야합니다.
: 그러니까 ScanLine(1) = ScanLine(0) - Width 이렇게 되죠
:
: 다시말하면 맨아랫줄 ScanLine(Height -1 ) 부터 한라인씩 파일에 기록되며
: 맨끝에 첫번째 라인이 기록됩니다.
:
: 보통 bmp파일이 그렇게 되어있구요
: TBitmap에서도 파일에 있는 순서대로 읽어옵니다.
:
:
: [PixcelFormat 에 대해]
: 프로그램에 보면 PixcelFormat = pf32bit 로 했잖아
: 32bit 는 4Byte 이므로 int * (int형 포인트)로 + , - 하면서 움직이면 한 Pixcel씩 움직이게 되죠
:
: 다시말해 ScanLine을 int * 로 받아왔기 때문에
: +1 ( 플러스 1 ) 또는 - 1 (마이너스 1 ) 하면 4Byte씩 주소가 움직이는겁니다.
: Width 만큼 더하거나 빼면 포인터가 4*Width 만큼 움직이겠죠
:
:
: 샘플 코드에 주석이 좀 부족했남?
:
: ==========================================================================================
: //---------------------------------------------------------------------------
: typedef struct _PIXCEL
: {
: int *pxl;
: int w;
: int h;
: }PIXCEL;
: //---------------------------------------------------------------------------
: bool __fastcall TForm1::FindIconRect(Graphics::TBitmap *bmp)
: {
: int wid=bmp->Width;
: int hei=bmp->Height;
:
: int * pt;
: ptLst->Clear();
: TRect rc;
: for(int h=0;h<hei;h++)
: {
: pt=(int *)bmp->ScanLine[h];
: for(int w=0;w<wid;w++)
: {
: if(*pt!=bkClr)
: {
: AddPixcel(pt,w,h);
: rc.left=w;
: rc.right=w;
: rc.top=h;
: rc.bottom=h;
: h=hei;
: break;
: }
: pt++;
: }
: }
:
: if(ptLst->Count<1)return false;
:
: PIXCEL *px;
: while(ptLst->Count) //특정 Pixcel로 부터 그와 연결된 모든 Pixcel을 찾아서 그pixcel들의 상/하/좌/우 가장자리를 찾는다.
: {
: px=(PIXCEL *)ptLst->Items[0];
:
: // 현재 pixcel이 지금까지 찾은 Rect 경계와 비교
: if(px->w<rc.left)rc.left=px->w;
: else if(px->w>rc.right)rc.right=px->w;
: if(px->h<rc.top)rc.top=px->h;
: else if(px->h>rc.bottom)rc.bottom=px->h;
:
:
: // 현재 Pixcel의 상/하/좌/우/대각선 4 군데서 벼경색 bkClr 과 다른색이 있는지 찾는다.
: if(px->w<(wid-1)) //오른쪽
: {
: pt=px->pxl+1; // 현재 Pixcel의 오른쪽 Pixcel 확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w+1,px->h);
: }
:
: }
: if(px->w > 0) //왼쪽
: {
: pt=px->pxl-1; // 현재 Pixcel의 왼쪽 Pixcel 확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w-1,px->h);
: }
: }
: if(px->h<(hei-1)) //아랫쪽
: {
: pt=px->pxl-wid; // 현재 Pixcel의 한 Line 아랫쪽 Pixcel확인
: // wid 만큼 빼면 Iimage에서 아랫쪽 line이 된다. ----------- 중요 :
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w,px->h+1);
: }
: //-----------------
: if(px->w<(wid-1)) //아랫쪽 -오른쪽 대각선
: {
:
: pt=px->pxl-wid+1; // 현재 Pixcel의 한 Line 아랫쪽 의 오른쪽 Pixcel확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w+1,px->h+1);
: }
:
: }
: if(px->w > 0) //아랫쪽 -왼쪽 대각선
: {
: pt=px->pxl-wid-1; // 현재 Pixcel의 한 Line 아랫쪽 의 왼쪽 Pixcel확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w-1,px->h+1);
: }
: }
: }
: if(px->h > 0)//윗쪽
: {
: pt=px->pxl+wid; // 현재 Pixcel의 한 Line 윗쪽 Pixcel확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w,px->h-1);
: }
: //-----------------
: if(px->w<(wid-1)) //윗쪽 -오른쪽 대각선
: {
:
: pt=px->pxl+wid+1; // 현재 Pixcel의 한 Line 윗쪽 의 오른쪽 Pixcel확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w+1,px->h-1);
: }
:
: }
: if(px->w > 0) //윗쪽 -왼쪽 대각선
: {
: pt=px->pxl+wid-1; // 현재 Pixcel의 한 Line 윗쪽 의 왼쪽 Pixcel확인
: if(*pt!=bkClr)
: {
: AddPixcel(pt,px->w-1,px->h-1);
: }
: }
: }
:
: px->pxl[0] =bkClr;
: ptLst->Delete(0);
: delete px;
:
: }
:
: //bitmap에서 방금 찾은 영역 Rect를 Clear한다.
: //그래서 다시 호출할때는 찾아지지 않도록
: bmp->Canvas->Pen->Color=bkClr;
: bmp->Canvas->Brush->Color=bkClr;
: bmp->Canvas->Brush->Style=bsSolid;
: bmp->Canvas->Rectangle(rc);
:
: String str;
: str.sprintf("%d , %d , %d , %d ",rc.left,rc.top,rc.right,rc.bottom); // 찾은 영역 Rect를 StringList에 기록해둔다.
: rcLst->Add(str);
:
: return true;
: }
: //---------------------------------------------------------------------------
: // 이미 같은 픽셀이 List에 등록되어잇는지 없는지 확인하구 없으면 추가한다.
: void __fastcall TForm1::AddPixcel(int *pt,int w,int h)
: {
: PIXCEL *pix;
: for(int i=0;i<ptLst->Count;i++)
: {
: pix=(PIXCEL *)ptLst->Items[i];
: if(pix->pxl==pt)return;
: }
: pix=new PIXCEL;
: pix->pxl=pt;
: pix->w=w;
: pix->h=h;
: ptLst->Add(pix);
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::Btn_FindIconsClick(TObject *Sender)
: {
: bkClr = ColorBox->Selected ;
: rcLst=new TStringList;
: ptLst=new TList;
: Image1->Picture->Bitmap->PixelFormat=pf32bit;
: Graphics::TBitmap *bmp=new Graphics::TBitmap;
: bmp->Assign(Image1->Picture->Bitmap);
: // int itic=GetTickCount();
:
: while(FindIconRect(bmp)); // 이미지의 Icon영역을 찾는다.
:
: // itic=GetTickCount()-itic;
: // ShowMessage(itic);
:
: TStringList *lst=new TStringList;
: TRect rc;
:
: Image1->Picture->Bitmap->Canvas->Pen->Color=clRed;
: Image1->Picture->Bitmap->Canvas->Brush->Style=bsClear;
:
: for(int i=0;i<rcLst->Count;i++) // 찾응 Icon영역을 TImage에 그려준다.
: {
: lst->Clear();
: lst->CommaText=rcLst->Strings[i];
: rc.left=StrToInt(lst->Strings[0]);
: rc.top=StrToInt(lst->Strings[1]);
: rc.right=StrToInt(lst->Strings[2])+1;
: rc.bottom=StrToInt(lst->Strings[3])+1;
: Image1->Picture->Bitmap->Canvas->Rectangle(rc);
:
: }
: delete lst;
: delete bmp;
: delete ptLst;
: delete rcLst;
: }
: //---------------------------------------------------------------------------
:
: 그럼..
:
:
: 한충희 님이 쓰신 글 :
: : 성호님 정말 죄송합니다 하루 왼종일 바도 모르겠어요
: : 그냥 가져다 쓰는 것도 말도 안되는거 같구
: : 정말 죄송하지만 픽셀 나가는 방향을 그림으로 아니면 순서라도
: : 알려주시면 안될까요???
: : 귀찮게 해서 죄송합니다
|