Link to home
Start Free TrialLog in
Avatar of abc88
abc88

asked on

visual c++ question......

below is Borland C++ builder code for display a histogram on frame Image3 based on the pixels information of *.bmp on Image1.....:-

void __fastcall TForm1::Open1Click(TObject *Sender)
{
  while (true)
  {
    if (OpenPictureDialog1->Execute())
    {
     Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
     POINT tPoint[256];                //coordinates
     int nHist[256];
                                       //clear all
     memset(nHist,0, sizeof(nHist));
     memset(tPoint,0, sizeof(tPoint));
                                       //create Hist: for all pixels
     for (int i = 0; i < Image1->Picture->Bitmap->Width; i++)
     {
      for (int j = 0; j < Image1->Picture->Bitmap->Height; j++)
      {
       long tColor1 = Image1->Picture->Bitmap->Canvas->Pixels[i][j];
       BYTE tColor = (BYTE)tColor1;
       nHist[tColor]++;                          //+1
      }
              //find Max of nHist
      int nMax = nHist[0];
      for (int i = 1; i < 256; i++)
       nMax = max(nMax,nHist[i]);
           //make point with coordinates
      for (int i = 0; i < 256; i++)
      {
       tPoint[i].x = (float)Image3->Width/ (float)(255)*(float)i;
       tPoint[i].y =  (float)Image3->Height*(1. - (float)nHist[i]/(float)nMax);
      }
     }
                    //display image
     Image1->Picture->Bitmap;
                    //display Graph
     Image3->Canvas->Polyline((const TPoint*)tPoint, 255);
     break;
    }
    else // user cancelled
    {
     break;
    }
  }
}

my question is:

any visual C++ experter here can show all the codes and command lines that conduct the same effect as what i did in BCB mentioned above if i want to do this in visual c++???
ASKER CERTIFIED SOLUTION
Avatar of AlexVirochovsky
AlexVirochovsky

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of abc88
abc88

ASKER

where can i find function formhistogramm in visual c++.....

As i know, the command line below is just display the image according to the coordinate on the surface of the created windows....and the image will get lose we move the window or we keep the window and oepn it again...it might not a suitable way...because we have to adjust the coordinate....

     BitBlt(dc,0,0,bm.bmWidth,bm.bmHeight,dch,0,0,SRCCOPY);
--------------------------
1.     Image1->Picture->Bitmap;
2.     Image3->Canvas->Polyline((const TPoint*)tPoint, 255);


uncle alex...
 do u know the command line for the mentioned above in visual c++......

i find that visual c++ is very confusing if compare to BCB...
Avatar of abc88

ASKER

for ur info., i call out two image frame from activeX control.....i try to use the same method as what i have done in BCB last time.....that is frame 1 is for display image and frame 2 is for display histogram....

i have tried some day in searching for the source code but i failed....

1.     Image1->Picture->Bitmap;
2.     Image3->Canvas->Polyline((const TPoint*)tPoint, 255);

the way of visual c++ is totally different.......
I don't think, that using ActiveX
Objects is good idea for this task.
If you want make sizeble Bitmap/Graph better use MDI interface , where 1-st Child is Bitmap,
2-nd: Graph.
As  i know, VC can make you
frame of MDI.
Alex
Avatar of abc88

ASKER

void CImagefilterDlg::OnFileOpen()
{
HWND hWnd;
char *szFileName;
      HBITMAP hBmp = (HBITMAP)LoadImage(NULL, szFileName,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (hBmp)
{
            CDC MemDC;
            CDC sourceDC,histDC;
COLORREF tAll[256];
int nColor=0;
POINT tPoint[256];
int i,j,nHist[256];
BITMAP bm;

memset(nHist,0,sizeof(nHist));
memset(tPoint,0,sizeof(tPoint));
memset(tAll,0, sizeof(tAll));
GetObject(hBmp, sizeof(bm), &bm);
//displat bitmap
HDC dc = GetDC(hWnd);
HDC dch = CreateCompatibleDC(dc);
SelectObject(dch, hBmp);
BitBlt(dc,0,0,bm.bmWidth,bm.bmHeight,dch,0,0,SRCCOPY);
for ( i = 0; i < bm.bmWidth;i++)
for ( j = 0; j < bm.bmHeight;j++)
{
COLORREF tColor = GetPixel(dc, i,j);
int k;
//exist such?
for (k = 0; k < nColor; k++)
if (tAll[k] == tColor)
break;
tAll[k] = tColor;
if (k == nColor)//new?
nColor++;
nHist[k]++;
}
int nMax = nHist[0];
for ( i = 1; i < 256;i++)
nMax = max(nMax,nHist[i]);
//say display from x= 0, y = 400 to x = 0,y = bm.bmHeight
//(small bitmap : bm.bmHeight < 400
for ( i = 0; i < nColor;i++)
{
tPoint[i].x = i + MINX;
tPoint[i].y = MAXY- nHist[i];
}
//display Graph
for ( i = 0; i < 256; i++)
SetPixel(dc,tPoint[i].x,tPoint[i].y,tAll[i]);
DeleteObject(hBmp);
ReleaseDC(hWnd,dc);
DeleteDC(dch);
}


there are 2 errors here:

C:\Program Files\Microsoft Visual Studio\MyProjects\thesis\imagefilterDlg.cpp(249) : error C2660: 'GetDC' : function does not take 1 parameters
C:\Program Files\Microsoft Visual Studio\MyProjects\thesis\imagefilterDlg.cpp(281) : error C2660: 'ReleaseDC' : function does not take 2 parameters
Error executing cl.exe.

imagefilter.exe - 2 error(s), 0 warning(s)

what should i do now???
Or , it is very easy:
If you use MFC (as in you example),
and global functions with same name,
you must set :: before global function.
You can or
1. change GetDC to ::GetDC //or
2. Use MFC analog: (usually without
    HWND parameter);
   GetDC();
Same with ReleaseDC.
   
Avatar of abc88

ASKER

class CImagefilterDlg : public CDialog
{
public:
      CImagefilterDlg(CWnd* pParent = NULL);            char *szFileName;
      HBITMAP hbmp;
      int nWidth;
      int nHeight;
}

-------------------

void CImagefilterDlg::OnFileOpen()
{
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, szFileName,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (hBmp)
{
COLORREF tAll[256];
int nColor=0;
POINT tPoint[256];
int i,j,nHist[256];
BITMAP bm;

memset(nHist,0,sizeof(nHist));
memset(tPoint,0,sizeof(tPoint));
memset(tAll,0, sizeof(tAll));
GetObject(hBmp, sizeof(bm), &bm);
//displat bitmap
HDC dc = GetDC();
HDC dch = CreateCompatibleDC(dc);
SelectObject(dch, hBmp);
BitBlt(dc,0,0,bm.bmWidth,bm.bmHeight,dch,0,0,SRCCOPY);
for ( i = 0; i < bm.bmWidth;i++)
for ( j = 0; j < bm.bmHeight;j++)
{
COLORREF tColor = GetPixel(dc, i,j);
int k;
//exist such?
for (k = 0; k < nColor; k++)
if (tAll[k] == tColor)
break;
tAll[k] = tColor;
if (k == nColor)//new?
nColor++;
nHist[k]++;
}
int nMax = nHist[0];
for ( i = 1; i < 256;i++)
nMax = max(nMax,nHist[i]);
//say display from x= 0, y = 400 to x = 0,y = bm.bmHeight
//(small bitmap : bm.bmHeight < 400
for ( i = 0; i < nColor;i++)
{
tPoint[i].x = i + MINX;
tPoint[i].y = MAXY- nHist[i];
}
//display Graph
for ( i = 0; i < 256; i++)
SetPixel(dc,tPoint[i].x,tPoint[i].y,tAll[i]);
DeleteObject(hBmp);
ReleaseDC(dc);
DeleteDC(dch);
}

there r still 2 errors:

C:\Program Files\Microsoft Visual Studio\MyProjects\thesis\imagefilterDlg.cpp(247) : error C2440: 'initializing' : cannot convert from 'class CDC *' to 'struct HDC__ *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files\Microsoft Visual Studio\MyProjects\thesis\imagefilterDlg.cpp(279) : error C2664: 'ReleaseDC' : cannot convert parameter 1 from 'struct HDC__ *' to 'class CDC *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

imagefilter.exe - 2 error(s), 0 warning(s)


i dunno how to solve it......can u teach me?????

From this text you can see, that
GetDC of FMC returns class CDC *.
For aboid this use 1-st option:
HDC dc = ::GetDC(hWnd);
and
::ReleaseDC(hWnd, dc);
Avatar of abc88

ASKER

void CImagefilterDlg::OnFileOpen()
{
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, szFileName,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (hBmp)
{
COLORREF tAll[256];
int nColor=0;
POINT tPoint[256];
int i,j,nHist[256];
BITMAP bm;

memset(nHist,0,sizeof(nHist));
memset(tPoint,0,sizeof(tPoint));
memset(tAll,0, sizeof(tAll));
GetObject(hBmp, sizeof(bm), &bm);
//displat bitmap
HDC dc = ::GetDC(hWnd);
HDC dch = CreateCompatibleDC(dc);
SelectObject(dch, hBmp);
BitBlt(dc,0,0,bm.bmWidth,bm.bmHeight,dch,0,0,SRCCOPY);
for ( i = 0; i < bm.bmWidth;i++)
for ( j = 0; j < bm.bmHeight;j++)
{
COLORREF tColor = GetPixel(dc, i,j);
int k;
//exist such?
for (k = 0; k < nColor; k++)
if (tAll[k] == tColor)
break;
tAll[k] = tColor;
if (k == nColor)//new?
nColor++;
nHist[k]++;
}
int nMax = nHist[0];
for (i = 1; i < 256;i++)
nMax = max(nMax,nHist[i]);
//say display from x= 0, y = 400 to x = 0,y = bm.bmHeight
//(small bitmap : bm.bmHeight < 400
for (i = 0; i < nColor;i++)
{
tPoint[i].x = i + MINX;
tPoint[i].y = MAXY- nHist[i];
}
//display Graph
for (i = 0; i < 256; i++)
SetPixel(dc,tPoint[i].x,tPoint[i].y,tAll[i]);
DeleteObject(hBmp);
::ReleaseDC(hWnd,dc);
DeleteDC(dch);
}
}


no error but cannot run and the screen show :-

"this program has performed an illegal operation and will be shut down.

if the problem persists, contact the programvendor."


for ur info., i use neither MDI nor SDI, but it's just a dialog based of MFC and i m affraid that the codes will be a bit different between them......so what is my next step???

i have tried the program as below and there's no error.....but the problem is the program can't show out the histogram..


void CImagefilterDlg::OnFileOpen()
{
      Invalidate();
      m_cProgress.SetPos(0);
      m_cProgress.GetPos();
      CClientDC ClientDC(this);
      CString FileName,FileExt;
      char szFilter[] = "Bitmap Files(*.BMP)|*.BMP|All Files(*.*)|*.*|";
      CFileDialog OpenImageFile(TRUE, NULL, NULL, OFN_HIDEREADONLY |
                      OFN_OVERWRITEPROMPT,szFilter,NULL);
      OpenImageFile.m_ofn.lpstrTitle = "Loading Image";
      if(IDOK == OpenImageFile.DoModal())
      {
            FileName = OpenImageFile.GetFileName();
            FileExt = OpenImageFile.GetFileExt();
            FileExt.MakeUpper();
            CDC MemDC;
          BITMAP bm;
            hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
            FileName,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
            GetObject(hbmp, sizeof(BITMAP), &bm );
          nWidth=bm.bmWidth;
           nHeight=bm.bmHeight;
            m_cProgress.SetRange(0,nHeight);
            MemDC.CreateCompatibleDC(NULL);
            HBITMAP hbmOldSource =
                  (HBITMAP)::SelectObject( MemDC.m_hDC, hbmp );
            int i,j,tColor;
        POINT tPoint[256];                //coordinates
        int nHist[256];
                                       //clear all
        memset(nHist,0, sizeof(nHist));
        memset(tPoint,0, sizeof(tPoint));
                                       //create Hist: for all pixels
            for(i=0;i<nHeight;i++)
            {
             for(j=0;j<nWidth;j++)
             {
          tColor = MemDC.GetPixel(i,j)&0x000000ff;
          nHist[tColor]++;                          //+1
             }
              //find Max of nHist
         int nMax = nHist[0];
         for (i = 1; i < 256; i++)
         nMax = max(nMax,nHist[i]);
            //make point with coordinates
         for (i = 0; i < 256; i++)
             {
              tPoint[i].x = i + MINX;
              tPoint[i].y = MAXY- nHist[i];
             }
             m_cProgress.SetPos(i + 1);
             m_cProgress.GetPos();
            }
            ::Polyline(MemDC,(CONST POINT*)tPoint,255);
            ClientDC.BitBlt(83,51,bm.bmWidth,bm.bmHeight,&MemDC,0,0,SRCCOPY);
      }
}

Well, i think the line:-

            ::Polyline(MemDC,(CONST POINT*)tPoint,255);
 
got a bit problem cuz this line seem no function at all.....

mm......any suggestions????
1.
>>for ur info., i use neither MDI nor >>SDI, but it's just a dialog based of >>MFC and i m affraid that the codes >>will be a bit different between >>them......so what is my next step???
Of course, this programm is for SDI
application and don't work in dialog!
In dialog you must make 2 Bitmaps
contols and overload Painting
for 1 : display Bitmap + find info
for 2: display Graph
2.
>> ::Polyline(MemDC,(CONST POINT*)>>tPoint,255);
>>ClientDC.BitBlt>>(83,51,bm.bmWidth,bm.bmHeight,&MemDC,0,0,SRCCOPY);
No, must be( i think, i am not MFC expert):
ClientDC->Polyline((CONST POINT*)tPoint,255);