none
How to get sub region of an image?

    Question

  • Dear all,

    I have an image loaded in a CImage object and now need to have a subImage, mean having a part of it as a new image. Is there any function which allows creating image from an existing image by specifying x and y offset and width and height ?

    Thanks.
    Tuesday, August 19, 2008 11:59 AM

Answers

  • Sorry, only tested it on 24-bit image. try this instead..

    CImage* createSubImage(CImage* src, int x, int y, int w, int h)  
    {  
      CImage* subImage = new CImage();  
      subImage->Create(w, h, src->GetBPP(), 0);  
      if ( src->IsIndexed() ) 
      { 
        int noOfCTableEntries = src->GetMaxColorTableEntries( ); 
        RGBQUAD* ctable = new RGBQUAD[noOfCTableEntries]; 
        src->GetColorTable(0, noOfCTableEntries, ctable); 
        subImage->SetColorTable(0, noOfCTableEntries, ctable); 
        delete [] ctable; 
      } 
      HDC hdc = subImage->GetDC();  
      src->BitBlt(hdc, 0, 0, w, h, x, y);  
      subImage->ReleaseDC();  
      return subImage;  
    }  

    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    Wednesday, August 20, 2008 8:23 AM

All replies

  • Something like...

    CImage* createSubImage(CImage* src, int x, int y, int w, int h) 
      CImage* subImage = new CImage(); 
      subImage->Create(w, h, src->GetBPP(), 0); 
      HDC hdc = subImage->GetDC(); 
      src->BitBlt(hdc, 0, 0, w, h, x, y); 
      subImage->ReleaseDC(); 
      return subImage; 

    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 6:34 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 6:49 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 6:50 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 6:50 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 6:50 AM
    Tuesday, August 19, 2008 2:09 PM
  • Thanks for your guidance. That seems to work but when I use

    subIamge->save(fileName);

    the resulting image is just a black image and it make me to doubt about it. What is wrong?
    • Edited by Ak-shokri Wednesday, August 20, 2008 6:55 AM new circumstance
    Wednesday, August 20, 2008 6:35 AM
  • Sorry, only tested it on 24-bit image. try this instead..

    CImage* createSubImage(CImage* src, int x, int y, int w, int h)  
    {  
      CImage* subImage = new CImage();  
      subImage->Create(w, h, src->GetBPP(), 0);  
      if ( src->IsIndexed() ) 
      { 
        int noOfCTableEntries = src->GetMaxColorTableEntries( ); 
        RGBQUAD* ctable = new RGBQUAD[noOfCTableEntries]; 
        src->GetColorTable(0, noOfCTableEntries, ctable); 
        subImage->SetColorTable(0, noOfCTableEntries, ctable); 
        delete [] ctable; 
      } 
      HDC hdc = subImage->GetDC();  
      src->BitBlt(hdc, 0, 0, w, h, x, y);  
      subImage->ReleaseDC();  
      return subImage;  
    }  

    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Unmarked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    • Marked as answer by Ak-shokri Wednesday, August 20, 2008 10:38 AM
    Wednesday, August 20, 2008 8:23 AM
  • Unfortunately result is still a black image but in specified dimension, e.g. of width w and height h.
    My image is a black and white jpeg, loaded in a CImage object. when I call save on this object, it works fine but for the created sub-image just a black image is saved.
    Wednesday, August 20, 2008 10:13 AM
  • I've tested that code using a 24-bit JPEG and it works fine. I suggest you post your code as maybe something else is causing it to fail.
    Wednesday, August 20, 2008 10:24 AM
  • You are right. I have been used the source cimage to get HBitmap handler first (using Detach()) and then attached again the hbitmap to it and called the createSubImage(...). By commentig the first part, it works correctly.

    Thanks for your reply. Do you know what the problem with my first approach is?
    Wednesday, August 20, 2008 10:37 AM
  • Once again, I suggest you post your (abbreviated) code as the steps you've suggested shouldn't prevent it from working.
    Wednesday, August 20, 2008 10:43 AM
  • This is the code (COM programming):
    static int main() 
    {    
        CoInitialize(NULL); 
         
        wchar_t filename[] = L"D:\\aShokri\\lines\\LN_01_11_SK000_PR1_SC1_FN_STNr_SZ10.jpg";     
        CImage cimage;  
        cimage.Load(filename); 
     
        HBITMAP hbmp = cimage.Detach(); 
          
        SRRF_OCR_LineSegmentation::ILineSegmenterPtr pILineSegmenter(__uuidof(SRRF_OCR_LineSegmentation::LineSegmenter)); 
        INT intptr = ((INT)hbmp); 
        pILineSegmenter->Segmenter(intptr); 
         
        SRRF_OCR_LineSegmentation::Seperators seperators;    
        seperators = pILineSegmenter->getSeperatorsInfo(); 
             
        //Accessing Members of returned structure 
        long lBound, uBound; 
        SafeArrayGetLBound(seperators.X, 1, &lBound); 
        SafeArrayGetUBound(seperators.X, 1, &uBound);    
     
        int xVal, yVal, x2, y2; 
        long j = 0; 
        SafeArrayGetElement(seperators.X, &j, &xVal); 
        SafeArrayGetElement(seperators.Y, &j, &yVal); 
     
        j = 1; 
        SafeArrayGetElement(seperators.X, &j, &x2); 
        SafeArrayGetElement(seperators.Y, &j, &y2); 
         
        cimage.Attach(hbmp);  //cimage.Load(filename); //both didn't work 
        CImage subImage;   
        subImage.Create(xVal-1000, yVal, cimage.GetBPP(), 0);   
        if ( cimage.IsIndexed() )  
         {  
            int noOfCTableEntries = cimage.GetMaxColorTableEntries( );  
            RGBQUAD* ctable = new RGBQUAD[noOfCTableEntries];  
            cimage.GetColorTable(0, noOfCTableEntries, ctable);  
            subImage.SetColorTable(0, noOfCTableEntries, ctable);  
            delete [] ctable;  
          }  
        HDC hdc = subImage.GetDC();   
        cimage.BitBlt(hdc, 0, 0, xVal-1000, yVal, xVal, yVal);   
        subImage.ReleaseDC();   
      
        wchar_t destFName[] = L"D:\\aShokri\\LN_01_11_SK000_seg01.jpg";  
        subImage.Save(destFName);   
     
        //Lci feature extraction 
        SRRF_OCR_LociFeatureExtraction::ILociFeaturesPtr pILociFeatures(__uuidof(SRRF_OCR_LociFeatureExtraction::LociFeatures)); 
        /*SRRF_OCR_LociFeatureExtraction::LuciResult luciFeatures = */ 
        pILociFeatures->Luci((INT)subImage.Detach(), 2, _bstr_t("01010101"), _bstr_t("WSN"),xVal, yVal, (xVal-x2), (yVal-y2) ); 
     
        DeleteObject(hbmp); 
        CoUninitialize(); 
     
        return 0; 
    }; 
    Wednesday, August 20, 2008 10:57 AM
  • Unfortunately that code isn't very helpful - If the image was being deleted/modified then it must be happening in the ILineSegmenterPtr::Segmenter call.

    As I cannot find any reference to that interface in the MSDN, I'm going to have to assume that it is one of your COM libraries or a third party one.

    Check the documentation to the interface to see if it destroys/modifies the passed HBITMAP, or if the library is yours - check the code!
    Wednesday, August 20, 2008 1:15 PM