CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jul 2010
    Posts
    2

    Taking a bitmap and stretching it to a new bitmap

    So I have been trying to create a stretched bitmap from a bitmap that I receive via a function call and stretch it so a user defined size.

    Here is my code that isn't working
    // I know my bitmap even stretched is not over 64k
    // For this please assume that bih and bmiHeader are valid if you find no problem with this code I can give you that information, 'thank you'.
    // pSubBuffer - Buffer of bitmap
    // bih is Bitmap info head for pSubBuffer
    // bmiHeader is requested new info for new bitmap

    BYTE* CreateStretchedBitmap(BYTE*pSubBuffer, BITMAPINFOHEADER bih, BITMAPINFOHEADER bmiHeader)
    {

    HDC hdcSrc = CreateCompatibleDC(NULL);
    HDC hdcDst = CreateCompatibleDC(NULL);
    HBITMAP hBit, hbmOld, hbmOld2, hbmNew;
    hBit = CreateDIBitmap(hdcSrc, &bih, CBM_INIT, (void*)pSubBuffer, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
    hbmNew = CreateDIBitmap(hdcDst, &bmiHeader, 0, NULL, NULL, DIB_RGB_COLORS);

    hbmOld = (HBITMAP)SelectObject(hdcSrc, hBit);
    hbmOld2 = (HBITMAP)SelectObject(hdcDst, hbmNew);

    SetStretchBltMode(hdcDst,HALFTONE);
    result = StretchBlt(hdcDst, 0,0, bmiHeader.biWidth, bmiHeader.biHeight, hdcSrc,0, 0, nWidth, nHeight, SRCCOPY);
    // result is 1 here

    HANDLE hDIB = GlobalAlloc(GHND, bmiHeader.biSizeImage);
    char *lpbitmap = (char *)GlobalLock(hDIB);
    result = GetDIBits(hdcDst, hbmNew, 0, bmiHeader.biHeight, lpbitmap, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS);
    // result returns 0 here and there is no error from GetLastError()

    SelectObject(hdcDst, hbmOld2);
    SelectObject(hdcSrc, hbmOld);
    BYTE * pOutBuffer = new BYTE[bmiHeader.biSizeImage];
    memcpy(pOutBuffer, lpbitmap, bmiHeader.biSizeImage);
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);
    DeleteDC(hdcSrc);
    DeleteDC(hdcDst);
    return pOutBuffer;
    }

  2. #2
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Taking a bitmap and stretching it to a new bitmap

    Please use code tags.

    Well it works for me ( I get a good value for "result" after calling GetDIBits ) after fixing the undefined nWidth, nHeight. I get a monochrome bitmap though. You need to pass a real DC to your CreateDIBitmap function otherwise your newly created memory DCs only have a monochrome bitmap. Try using the desktop DC instead:

    Code:
      //Add this line:
      HDC hdcDesktop = GetDC(NULL);
      HDC hdcSrc = CreateCompatibleDC(NULL);
      HDC hdcDst = CreateCompatibleDC(NULL);
      HBITMAP hBit, hbmOld, hbmOld2, hbmNew;
      hBit = CreateDIBitmap(hdcDesktop, &bih, CBM_INIT, (void*)pSubBuffer, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
      hbmNew = CreateDIBitmap(hdcDesktop, &bmiHeader, 0, NULL, NULL, DIB_RGB_COLORS);
      //the rest is the same except I changed to get it to compile:
      result = StretchBlt(hdcDst, 0,0, bmiHeader.biWidth, bmiHeader.biHeight, hdcSrc,0, 0, bih.biWidth, bih.biHeight, SRCCOPY);

  3. #3
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Taking a bitmap and stretching it to a new bitmap

    This is how I called your function (assumes a 32bit bitmap on input):
    Code:
    void CTestView::OnBnClickedButton1()
    {
      FILE *f1,*f2;
      BITMAPINFOHEADER bi1={0};
      BITMAPINFOHEADER bi2={0};
      BITMAPFILEHEADER fh1={0};
      unsigned char *buf,*p;
      int newwidth=1000,newheight=1000;
      
      _wfopen_s(&f1,L"c:/in.bmp",L"rb");
      _wfopen_s(&f2,L"c:/out.bmp",L"wb");
      fread(&fh1,sizeof(BITMAPFILEHEADER),1,f1);
      fread(&bi1,sizeof(BITMAPINFOHEADER),1,f1);
      buf=new unsigned char[bi1.biSizeImage];
      size_t sz=fread(buf,1,bi1.biSizeImage,f1);
      fclose(f1);
      bi2=bi1;
      bi2.biHeight=newheight;
      bi2.biWidth=newwidth;
      bi2.biSizeImage=(newwidth*newheight*4);
      p=CreateStretchedBitmap(buf,bi1,bi2);
      fh1.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(newwidth*newheight*4);
      fwrite(&fh1,sizeof(BITMAPFILEHEADER),1,f2);
      fwrite(&bi2,sizeof(BITMAPINFOHEADER),1,f2);
      fwrite(p,(newwidth*newheight*4),1,f2);
      fclose(f2);
      delete[] buf;
      delete[] p;
    }

  4. #4
    Join Date
    Jul 2010
    Posts
    2

    Re: Taking a bitmap and stretching it to a new bitmap

    I tried using your code and it doesn't seem to work in my particular case. The bibitCount is not always 32 since it will depend on the device. The Original BITMAPINFOHEADER comes from a VIDEOINFOHEADER which in turn is from an AM_MEDIA_TYPE. Here is the bih
    Code:
    bih.biSize = 40;
    bih.biWidth = 440;
    bih.biHeight = 200;
    bih.biPlanes = 1;
    bih.biBitCount = 16;
    bih.biCompression = 844715353;
    bih.biSizeImage = 176000;
    every other parameter is 0 for this.
    I tried using your code and it doesn't seem to work in my particular case.

  5. #5
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Taking a bitmap and stretching it to a new bitmap

    Hmmm. I have no idea what 844715353 compression code is. It's not one I've heard of. I'm afraid I can't help you with that one.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured