그림 형식 변환

(1):원본 링크:http://blog.csdn.net/jtujtujtu/article/details/3734722
Gdiplus::Bitmap 변환 IplImage
  // pIplImage        Mosesyuan
     void CGeneral::BitmapToIplImage(Bitmap* pBitmap, IplImage* &pIplImg)
    {
        if (!pBitmap)
        {
            return;
        }
        if(pIplImg)
        {
            cvReleaseImage(&pIplImg);
            pIplImg = NULL;
        }
        BitmapData bmpData;
        Rect rect(0,0,pBitmap->GetWidth(),pBitmap->GetHeight());
        pBitmap->LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bmpData);
        IplImage* tempImg = cvCreateImage(cvSize(pBitmap->GetWidth(), pBitmap->GetHeight()), IPL_DEPTH_8U, 3);
        BYTE* temp = (bmpData.Stride>0)?((BYTE*)bmpData.Scan0):((BYTE*)bmpData.Scan0+bmpData.Stride*(bmpData.Height-1));
        memcpy(tempImg->imageData, temp, abs(bmpData.Stride)*bmpData.Height);
        pBitmap->UnlockBits(&bmpData);
        pIplImg = tempImg;
    //  Top-Down or Bottom-Up
        if (bmpData.Stride<0)        
            cvFlip(pIplImg, pIplImg);            
    }

OpenCV 에서 IplImage 전환 Gdiplus::Bitmap
    // pBitmap         !!
    void CGeneral::IplImageToBitmap(IplImage* pIplImg, Bitmap* &pBitmap)
    {
        if(!pIplImg)
            return;        
        BITMAPINFOHEADER bmih;
        memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
        bmih.biSize = sizeof(BITMAPINFOHEADER);
        bmih.biWidth = pIplImg->width;
        bmih.biHeight = pIplImg->height;
        bmih.biPlanes = 1;
        bmih.biBitCount = pIplImg->depth*pIplImg->nChannels;
        bmih.biSizeImage = pIplImg->imageSize;
        BYTE* pData=new BYTE[bmih.biSizeImage];
        memcpy(pData, pIplImg->imageDataOrigin, pIplImg->imageSize);
        if (pBitmap)
        {
            delete pBitmap;
            pBitmap = NULL;
        }
        pBitmap = Gdiplus::Bitmap::FromBITMAPINFO((BITMAPINFO*)&bmih, pData);
    }

테스트 를 통 해 사용 할 수 있 습 니 다.문제 가 있 으 면 토론 을 환영 합 니 다!
(2):VC Picture 컨트롤 의 로 딩 이미지 사용 총화
글 의 출처:http://wenku.baidu.com/view/57fe877ea26925c52cc5bf41.html
(1) 비 동적 디 스 플레이 그림(즉,그림 은 자원 관리자 로 불 러 오고 고정 ID 가 있 음)(2) 그림 을 동적 으로 불 러 옵 니 다(즉,프로그램 에서 그림 의 경 로 를 지정 하면 불 러 옵 니 다)
설명 을 편리 하 게 하기 위해 서,우 리 는 대화 상 자 를 기반 으로 하 는 프로젝트 를 만 들 었 습 니 다.이름 은 Ttest 이 고,대화 상 자 는 CTestDlg 입 니 다.
(1)vc picture 컨트롤 비 동적 으로 그림 을 불 러 옵 니 다.
방법 1.가장 쉬 운 것 부터 시작 해서 picture 로 컨트롤 이 실 현 됩 니 다.단계:자원 에 그림 한 장 을 가 져 옵 니 다.ID 는 IDB 입 니 다.BITMAP 2,그리고 대화 상자 에 picture 컨트롤 을 추가 합 니 다.오른쪽 단 추 를 누 르 면 속성 을 엽 니 다.type 드 롭 다운 상 자 를 BITMAP 로 선택 하고 아래 에 Image 드 롭 다운 상자 가 나타 납 니 다.열 면 불 러 온 모든 그림 을 볼 수 있 습 니 다.원 하 는 그림 을 선택 하 십시오.프로그램 을 실행 하면 볼 수 있 습 니 다.
방법 2.vc picture 컨트롤.배경 그림 을 통 해 위 와 같이 그림 을 불 러 옵 니 다.ID 는 IDB 입 니 다.BITMAP2
TestDlg.h 중 CBrush mbrBk;//Public 에서 정의
TestDlg.cpp 에 초기 화 함수 OnInitDialog()에 추가:
클래스 마법사 열기,WM 찾기CTLCOLOR 메시지,대응 하 는 함수 OnCtlColor()를 다시 불 러 옵 니 다.다음 과 같이 추가 합 니 다.
BOOL CTestDlg::OnInitDialog()
{
   CDialog::OnInitDialog();
   CBitmap bmp;
   bmp.LoadBitmap(IDB_BITMAP2);
   m_brBk.CreatePatternBrush(&bmp);
   bmp.DeleteObject();
   return TRUE;   // return TRUE   unless you set the focus to a control
}

(2)vc picture 컨트롤 이 그림 을 동적 으로 불 러 옵 니 다.
방법 이미지 컨트롤 그림 편집 컨트롤)1.우선 시스템 에 이 컨트롤 이 있 는 지 확인 해 야 합 니 다.단독으로 사용 할 수 없습니다.다른 컨트롤(특히 Imgcmn.dll)과 함께 사용 해 야 합 니 다.없 으 면 다른 기계 에서 복사 하면 됩 니 다.이 몇 개의 파일 은 Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll 로 windows\system 디 렉 터 리 에 복사 한 다음 regsvr 32.exe 로 각각 등록 합 니 다.2.프로젝트 를 열 고 자원 관리자 에 들 어가 대화 상자 에서 오른쪽 단 추 를 누 르 고 Insert Activex control 을 누 르 면... Kodak 이미지 편집 컨트롤 을 선택 하 십시오.크기 가 임의의 것 입 니 다.3.대화 상자 에서 이 컨트롤 을 선택 하고 변 수 를 추가 합 니 다:mctrlPicture。。 4.BOOL CTestDlg::OnInitDialog()에 다음 과 같이 추가 합 니 다.
4.567913.컴 파일 이 실행 되면 OK 입 니 다.이 방법의 장점 은 여러 가지 이미지 형식 에 대한 것 입 니 다.
방법 4.vc picture 컨트롤 은 CBitmap,HBITMAP 를 통 해 OnPaint()로 먼저 CTestDlg 류 에서 변 수 를 설명 합 니 다.          CBitmap   m_bmp; 그리고 저희 가 대화 상자 에 picture 를 하나 넣 을 게 요. 태그,이름 은 IDCSTATIC 1,그리고:
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   if (pWnd == this)
{
   return m_brBk;
}
   return hbr;
}

그림 불 러 오 는 데 성 공 했 습 니 다.태그 크기 도 적 응 했 습 니 다.다음은 그림 그리 기 입 니 다.클래스 마법 사 를 열 고 WM 을 다시 불 러 옵 니 다.PAINT 메시지
BOOL CTestDlg::OnInitDialog()
{
      CDialog::OnInitDialog();
      m_ctrlPicture.SetImage("aa.jpg");   //          ,        
      m_ctrlPicture.Display();
      return TRUE;   // return TRUE unless you set the focus to a control
                     // EXCEPTION: OCX Property Pages should return FALSE
}

상기 네 가지 방법 은 KoDak 만 다양한 그림 을 지원 할 수 있 고 다른 것 은 BMP 만 지원 합 니 다.
(3):
HBITMAP 와 Bmp 작업 인식(전체 메모리 복사 판)
원본 링크:http://www.zwqxin.com/archives/image-processing/bmp-operate-copy-memory.html
본문 은 ZwqXin (http://www.zwqxin.com/),전재      원본 주소:http://www.zwqxin.com/archives/image-processing/bmp-operate-copy-memory.html
창의 그 순환 은 매번 픽 셀 을 하나씩 화면 창 에 인쇄 해 야 한 다 는 것 을 알 아야 합 니 다.(간단 한 SetPixel 을 통 해)창 을 이동 하면 뼈 에 사무 치 는 지연 을 느 낄 수 있 습 니 다.어떻게 이렇게 느 릴 수 있 습 니까?만약 내 가 FPS 를 계산 하 러 간다 면,그것 은 정말 몇 프레임/초 밖 에 없 을 것 이다.하지만 나의 WIN 32 는 프레임 기반 의 순환 에 의존 해 야 한다!다른 방법 으로 BMP 데 이 터 를 처리 할 수 밖 에 없다.
Blit 라 는 단 어 는 나 에 게 매우 인상적 이 었 다.먼저 glBlitFramebufferEXT(OpenGL 이 FBO 와 스크린 에 동시에 렌 더 링 하 는 것 과 어떻게 비슷 한 지)가 이런 기술 의 대단 함 을 보 았 고,그 다음은 WINDOWS 게임 프로 그래 밍 마스터 기법 제6 장 에서 DIRECTDRAW 의 blit 기술 을 언급 했다.응,사실은 다 똑 같은 거 야.화면 창 에 표시 되 기 를 원 하 는 내용 을 화면 등 큰 메모리 에 미리 넣 고 표시 해 야 할 때 이 메모리 의 데 이 터 를 화면 에 한 번 에 비 추 는 것 입 니 다.BMP 를 읽 을 때 BMP 데이터 의 저장 위 치 는 전편 과 다 릅 니 다.더 이상 COLORREF 의 여러 그룹 이 아니 라 Blit 메모리 로 지 명 됩 니 다.이것 은 모두 BMP 의 불 러 오 는 과정 에서 이 루어 집 니 다.BMP 불 러 오 는 것 은 한 번 만 실 행 됩 니 다.WIN 32 프로그램 순환 에서 그림 을 표시 하려 면 이 메모리 BLIT 에서 픽 셀 데 이 터 를 화면 으로 내 면 됩 니 다.
응,말 하기는 쉬 워.하기 가 쉽 지 않 아.지명내 가 할 수 있 을 까?그 럴 리 가 없 잖 아.지명 이란 WINDOWS 에 맡 겨 야 한다.확실히 또 WIN 32 API 에 빠 져 야 합 니 다..................................................................................하면,만약,만약...FILE 가 HBITMAP 로 설명 할 수 있 는(WINDOWS 가 알 고 있 는)대상 으로 바 뀌 면 우 리 는 WIN 32 의 BitBlt 또는 StretchBlt 함수 API 로 HBITMAP 가 설명 한 대상 이 있 는 메모리 영역 을 화면 으로 복사 할 수 있 습 니 다.
우선,앞 장면 을 넘 어 갑 니 다.
BOOL CDisplayPic::OnInitDialog()
{
     CDialog::OnInitDialog();
     if( m_bmp.m_hObject != NULL )//  
         m_bmp.DeleteObject();
     //    
     HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
         "c:\\aaa.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
     if( hbmp == NULL )
         return FALSE;
     //           BMP   //
     m_bmp.Attach( hbmp );
     DIBSECTION ds;
     BITMAPINFOHEADER &bminfo = ds.dsBmih;
     m_bmp.GetObject( sizeof(ds), &ds );
     int cx=bminfo.biWidth;   //      
     int cy=bminfo.biHeight; //      
     /////////////////// ////////////////////////////////
     //            ,              ,
     //        ,          
     ////////////////////////////////////////////////////
     CRect rect;
     GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);
     ScreenToClient(&rect);
     GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,cy,true);//    
     return TRUE;   // return TRUE unless you set the focus to a control
                    // EXCEPTION: OCX Property Pages should return FALSE
}

보이 시 나 요?BMP 데이터 영역 에 있 는 데 이 터 를 읽 기 전에 메모리 기반 DC:BmpDC 를 만 듭 니 다.BMP 그림 을 표시 할 화면 창 과 호 환 됩 니 다.(DrawDeviceHandler 는 창 클 라 이언 트 영역 DC 입 니 다.)그리고 저희 만 의 BITMAPFILE 의 데이터 영역 이 데 이 터 를 채 우기 전에 CreateDIBSection 으로 HBITMAP 를 만 듭 니 다.그것 이 만 든 HBITMAP 는 DIB(장치 와 상 관 없 이 독립 된 BITMAP)를 묘사 하 는데 필요 한 매개 변 수 는 자명 하 다.그 중에서 마지막 세 번 째 는 데이터 구역 의'시작 주소 의 주소'이다.기억 하 세 요.이 DIB 의 Section 을 먼저 만 든 다음 에 채 워 진 데이터 만 유효 하기 때문에 장치 와 무관 한 DIB 는 Create DIBSection 후에 야 진정한 데 이 터 를 불 러 올 수 있 습 니 다!(나 는 모퉁이 를 돌 았 다.지금 너 는 이 졸작 을 보고 네가 모퉁이 를 적 게 돌 았 으 면 좋 겠 다~)를 본 후에 일부 SelectObject(BmpDC,mBMP)를 표시 한 후에 BitBlt 라 는 함수 로 그림 을 전달 하 는 일 을 할 수 있다.
DIB 와 DDB,여 기 를 참고 하 세 요.내 가 이해 하 는 것 은 전 자 는 당신 의 시스템 장치 에 독립 되 어 있 습 니 다.마치 BMP 형식의 그림 처럼 당신 이 누구의 컴퓨터 에 전송 하 는 지,그/그녀의 컴퓨터 장치 가 어떻게 괜 찮 은 지,그 가 BMP 를 여 는 소프트웨어(예 를 들 어 XP 자체 의 그래 픽 프로그램)만 있 으 면 이 BMP 를 볼 수 있 고 다 르 지 않 습 니 다.데이터 가 똑 같 기 때 문 입 니 다.한편,DDB(장치 관련 그림)는 시스템 장치 에 의존 합 니 다.다시 말 하면 장 치 를 떠 나 독립 적 으로 존재 할 수 없고 WINDOWS 내부 에서 픽 셀 색상 정보 에 대한 추상 적 인 표현 입 니 다.DIB(WINDOWS 에서 직접 조작 할 수 있 는 비트 맵 구조)에 대해 저 희 는 CreateDIBSection 으로 HBITMAP 가 설명 한 OBJECT 를 되 돌려 줍 니 다.DDB 에 대해 서 는 CreateDIBitmap 으로 만 듭 니 다.
8 비트 맵 에 팔레트 가 있 는데 팔레트 라 는 것 은 사실 매우 복잡 하 다.대체적으로 그림 에 내 장 된 팔레트 를 제외 하고 모든 그림 환경(DC)은 그 에 속 하 는 논리 팔레트 가 있 고 시스템 자체 에 도 하나 있다 는 것 을 이해 합 니 다.위 에서 말 했 듯 이 그 레이스 케 일이 아 닌 8BIT 이미지 데이터 구역 에 있 는'픽 셀 대응 BYTE'는 팔레트 배열 에 대응 하고 배열 의 모든 요소 가 하나의 색 을 표시 합 니 다.문 제 는'색깔'이라는 두 글자 에 있다.여기 서 정확 한 표현 은'색깔 값'이다.예 를 들 어(25,255,0)이다.그런데 시스템 이 어떻게 팔레트 에 있 는(25,255,0)이 노란색 이라는 것 을 알 수 있 습 니까?이전 전편 에 서 는 색상 을 하나의 COLORREF 배열 로 옮 긴 다음 에 창 DC 를 통 해 RGB(*,*,*)를 호출 할 때 시스템 은 RGB 매크로 를 알 고 COLORREF(자신의 데이터 구 조 를 알 수 있 습 니 다)를 알 수 있 습 니 다.이전 8 위 이상 BMP 에서 DIB 는 시스템 과 상 관 없 이 어떤 팔레트 를 모 르 고 시스템 과 직접 대 화 를 했 습 니 다.저 는 XXX 색상 을 원 합 니 다.음흉 하 게 웃다.그러나 8BIT 그림(또는 이하)의 팔레트 는 그 능력 이 없습니다.화면 창 DC 에 비 친 후 이 DC 의 논리 팔레트 에서 시스템 팔레트 와 통화 하고 시스템 팔레트 에 시스템 이 정 한 정확 한 색상 을 얻 기 위해'방 권'을 요청 해 야 합 니 다.(구체 적 인 내용 은 참고 하 시기 바 랍 니 다.http://cs.ccnu.edu.cn/datastruct/download/waiweikecheng/VC/chap11_1.htm)
ZwqXin 이 우여곡절 끝 에 8BIT 이미지 의 정확 한 불 러 오기 와 표시 가 나 왔 습 니 다.
void CDisplayPic::OnPaint()
{
//////////////                (      )///////////

     //CPaintDC dc(this);       //    ,        DC,           .
     CPaintDC dc(GetDlgItem(IDC_STATIC1)); //   ,  picture   DC,          
     //CDC dc;
     //dc.m_hDC=::GetDC(NULL);   //     ,       DC,          
///////////////////////////////////////////////////////
     CRect rcclient;
     GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient);
     CDC memdc;
     memdc.CreateCompatibleDC(&dc);
     CBitmap bitmap;
     bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
     memdc.SelectObject( &bitmap );
     CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);

     CDC maskdc;
     maskdc.CreateCompatibleDC(&dc);
     CBitmap maskbitmap;
     maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
     maskdc.SelectObject( &maskbitmap );
     maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,
         rcclient.left, rcclient.top, SRCCOPY);

     CBrush brush;
     brush.CreatePatternBrush(&m_bmp);
     dc.FillRect(rcclient, &brush); 
     dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
              &memdc, rcclient.left, rcclient.top,SRCPAINT);
     brush.DeleteObject();
     // Do not call CDialog::OnPaint() for painting messages
}

절 차 는 다음 과 같 습 니 다.BMP 파일 의 팔레트 를 읽 고 논리 팔레트 구조(LOGPALETTE)를 만 듭 니 다.즉,창 DC 에 보 여 주 려 는 것 입 니 다.(생 성 과정 은 LOGPALETTE 구조 에 정 보 를 채 우 는 것 입 니 다),HPALETTE mPalette 역시 팔레트 OBJECT 를 설명 하 는 핸들(팔레트 핸들)입 니 다.저 희 는 Create Palette(LOGPALETTE)를 통 해  logpal)함수 가 실제 WINDOWS 인식 을 위 한 논리 팔레트 OBJECT 를 만 듭 니 다.SelectPalette 는 DC 에 논리 팔레트 를 선택 한 다음(여기 가 현재 화면 창 DrawDeviceHandler 입 니 다)RealizePalette 는 이 논리 팔레트 를 시스템 팔레트 에 구현 합 니 다(시스템 과 의 교섭).
그 다음 단 계 는 DIB 를 만 드 는 것 과 크게 다 르 지 않다.그러나 장 치 를 만 드 는 데 사용 되 는 그림 DDB 와 무관 한 CreateDIBitmap 입 니 다.매개 변 수 는 자명 합 니 다.하지만 이번 에는 DDB 를 만 들 기 전에 데 이 터 를 읽 어야 합 니 다.그렇지 않 으 면 팔레트 의 어떤 색 을 사용 해 야 할 지 모 릅 니 다.참,DDB 입 니 다.이 BitBlt 야,StretchBlt 는 읽 을 수 있 나 요?사실 읽 기 전에 BMP 비트 맵 의 메모리 DC 와 창 화면 DC 를 모두 이 논리 팔레트 mPalette 와 일치 시 키 면 틀림 없습니다.어?전에 맞 췄 잖 아 요.네,그래서 저 는 이 단 계 를 빼 도 8BIT 그림 을 정확하게 읽 을 수 있 습 니 다.하지만 나 같은 반찬 새 에 게 만일 이 라면.......................................................
    bool OperateBMP::LoadBmp(const char *filename)
    {
     
        ifstream fileBmp;
        fileBmp.open(filename,ios::binary);
     
        if (!fileBmp)
        {
            MessageBox(NULL, "     ", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
            fileBmp.close();
            return false;
        }
        
     
       fileBmp.read( (char*)&bitmap.bitmapheader, sizeof(BITMAPFILEHEADER) );
     
       if(bitmap.bitmapheader.bfType != 0x4D42)
       {
            fileBmp.close();
            MessageBox(NULL, "  0x4D42-BMP", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
            return false;
       }
     
       fileBmp.read( (char*)&bitmap.bitmapinfoheader, sizeof(BITMAPINFOHEADER) );
       BmpBit = bitmap.bitmapinfoheader.biBitCount;
     
       if(bitmap.bitmapinfoheader.biSizeImage > 0)
           BmpDataSize = bitmap.bitmapinfoheader.biSizeImage;
       else
           BmpDataSize = bitmap.bitmapinfoheader.biWidth * 
    bitmap.bitmapinfoheader.biBitCount * bitmap.bitmapinfoheader.biHeight;
    //(TO BE CONTINUED)

         (<=8BIT   )   (>8BIT   ),    HBITMAP     ,        :

    ( TO BE CONTINUED )
     
       fileBmp.seekg((BmpDataSize)*(-1), ios::end);
     
       bitmap.buffer = new UCHAR[BmpDataSize];
       memset(bitmap.buffer,0,BmpDataSize);
     
        BmpDC = CreateCompatibleDC(DrawDeviceHandler);
     
      //if  BmpBit > 8
        if(bitmap.buffer != NULL)bitmap.buffer = NULL;  
        mBMP = CreateDIBSection(BmpDC, (BITMAPINFO *)&bitmap.bitmapinfoheader, 
        DIB_RGB_COLORS, (void **)&bitmap.buffer, NULL, 0);
     
       fileBmp.read( (char*)bitmap.buffer, bitmap.bitmapinfoheader.biSizeImage );
     
       fileBmp.close();
    ....//         
    }
    //            :
        BITMAP_FILE bitmap;
        HDC BmpDC;
        HBITMAP mBMP;
     
        HDC  DrawDeviceHandler; 

이곳 의 ShowBmp 는 클 라 이언 트 구역 에서 출발점 을 지정 합 니 다.사이즈(원 그림 사이즈 가 좋 습 니 다.원 그림 이 너무 큰 손님 들 은 StretchBlt 로 그림 을 전달 하 는 것 을 고려 하여 BLIT 의 목표 크기 를 조절 할 수 있 습 니 다)그림 을 표시 합 니 다.WIN 32 순환 에 넣 으 세 요!
저장 절 차 는 전편 과 차이 가 많 지 않 습 니 다.(8BIT 그림 은 원본 팔레트 를 저장 해 야 합 니 다.)중복 되 지 않 습 니 다.그래,나 피곤 해,피곤 해,정말 피곤 해.......................................................

좋은 웹페이지 즐겨찾기