c++ - Saving bitmap problems in winapi -
it writes bitmap.bmp file when try view in windows photo viewer says "windows photo viewer can't open picture because file appears damaged, corrupted, or large." know should have put functions header files haven't ever delved enough project make header files forgot how. if knows size limit pictures in windows photo viewer thankful. , got of these functions msdn(unashamed). error handling better don't have errorhandler.h. not sure how of functions work because said used code msdn. appreciative of can me. :)
#include <errorrep.h> #include <windows.h> #include <iostream> using namespace std; namespace globals{ hbitmap hbitmap; hdc hscreen; } using namespace globals; void getscreenshot(void) { int x1, y1, x2, y2, w, h; lpsize lpsize; lpvoid lpvbits; // screen dimensions x1 = getsystemmetrics(sm_xvirtualscreen); x2 = getsystemmetrics(sm_cxvirtualscreen); y1 = getsystemmetrics(sm_yvirtualscreen); y2 = getsystemmetrics(sm_cyvirtualscreen); w = x2-x1; h = y2-y1; // copy screen bitmap hscreen = getdc(null); hdc hdc = createcompatibledc(hscreen); hbitmap = createcompatiblebitmap(hscreen, w, h); hgdiobj old_obj = selectobject(hdc, hbitmap); bool bret = bitblt(hdc, 0, 0, w, h, hscreen, x1, y1, srccopy); getbitmapdimensionex(hbitmap, lpsize); getbitmapbits(hbitmap, (long)lpsize, lpvbits); // save bitmap clipboard openclipboard(null); emptyclipboard(); setclipboarddata(cf_bitmap, hbitmap); closeclipboard(); // clean selectobject(hdc, old_obj); /*deletedc(hdc); releasedc(null, hscreen); deleteobject(hbitmap);*/ } pbitmapinfo createbitmapinfostruct(/*hwnd hwnd, */hbitmap hbmp) { bitmap bmp; pbitmapinfo pbmi; word cclrbits; // retrieve bitmap color format, width, , height. if (!getobject(hbmp, sizeof(bitmap), (lpstr)&bmp)) //errhandler("getobject", hwnd); cout << "error: createbitmapinfostruct" << endl; // convert color format count of bits. cclrbits = (word)(bmp.bmplanes * bmp.bmbitspixel); if (cclrbits == 1) cclrbits = 1; else if (cclrbits <= 4) cclrbits = 4; else if (cclrbits <= 8) cclrbits = 8; else if (cclrbits <= 16) cclrbits = 16; else if (cclrbits <= 24) cclrbits = 24; else cclrbits = 32; // allocate memory bitmapinfo structure. (this structure // contains bitmapinfoheader structure , array of rgbquad // data structures.) if (cclrbits < 24) pbmi = (pbitmapinfo) localalloc(lptr, sizeof(bitmapinfoheader) + sizeof(rgbquad) * (1<< cclrbits)); // there no rgbquad array these formats: 24-bit-per-pixel or 32-bit-per-pixel else pbmi = (pbitmapinfo) localalloc(lptr, sizeof(bitmapinfoheader)); // initialize fields in bitmapinfo structure. pbmi->bmiheader.bisize = sizeof(bitmapinfoheader); pbmi->bmiheader.biwidth = bmp.bmwidth; pbmi->bmiheader.biheight = bmp.bmheight; pbmi->bmiheader.biplanes = bmp.bmplanes; pbmi->bmiheader.bibitcount = bmp.bmbitspixel; if (cclrbits < 24) pbmi->bmiheader.biclrused = (1<<cclrbits); // if bitmap not compressed, set bi_rgb flag. pbmi->bmiheader.bicompression = bi_rgb; // compute number of bytes in array of color // indices , store result in bisizeimage. // width must dword aligned unless bitmap rle // compressed. pbmi->bmiheader.bisizeimage = ((pbmi->bmiheader.biwidth * cclrbits +31) & ~31) /8 * pbmi->bmiheader.biheight; // set biclrimportant 0, indicating of // device colors important. pbmi->bmiheader.biclrimportant = 0; return pbmi; } void createbmpfile(/*hwnd hwnd, */lptstr pszfile, pbitmapinfo pbi, hbitmap hbmp, hdc hdc) { handle hf; // file handle bitmapfileheader hdr; // bitmap file-header pbitmapinfoheader pbih; // bitmap info-header lpbyte lpbits; // memory pointer dword dwtotal; // total count of bytes dword cb; // incremental count of bytes byte *hp; // byte pointer dword dwtmp; pbih = (pbitmapinfoheader) pbi; lpbits = (lpbyte) globalalloc(gmem_fixed, pbih->bisizeimage); if (!lpbits) //errhandler("globalalloc", hwnd); cout << "!lpbits" << endl; // retrieve color table (rgbquad array) , bits // (array of palette indices) dib. if (!getdibits(hdc, hbmp, 0, (word) pbih->biheight, lpbits, pbi, dib_rgb_colors)) { //errhandler("getdibits", hwnd); cout << "error 1" << endl; } // create .bmp file. hf = createfile(pszfile, generic_read | generic_write, (dword) 0, null, create_always, file_attribute_normal, (handle) null); if (hf == invalid_handle_value) //errhandler("createfile", hwnd); hdr.bftype = 0x4d42; // 0x42 = "b" 0x4d = "m" // compute size of entire file. hdr.bfsize = (dword) (sizeof(bitmapfileheader) + pbih->bisize + pbih->biclrused * sizeof(rgbquad) + pbih->bisizeimage); hdr.bfreserved1 = 0; hdr.bfreserved2 = 0; // compute offset array of color indices. hdr.bfoffbits = (dword) sizeof(bitmapfileheader) + pbih->bisize + pbih->biclrused * sizeof (rgbquad); // copy bitmapfileheader .bmp file. if (!writefile(hf, (lpvoid) &hdr, sizeof(bitmapfileheader), (lpdword) &dwtmp, null)) { //errhandler("writefile", hwnd); cout << "!writefile" << endl; } // copy bitmapinfoheader , rgbquad array file. if (!writefile(hf, (lpvoid) pbih, sizeof(bitmapinfoheader) + pbih->biclrused * sizeof (rgbquad), (lpdword) &dwtmp, ( null))) //errhandler("writefile", hwnd); cout << "!writefile" << endl; // copy array of color indices .bmp file. dwtotal = cb = pbih->bisizeimage; hp = lpbits; if (!writefile(hf, (lpstr) hp, (int) cb, (lpdword) &dwtmp,null)) //errhandler("writefile", hwnd); cout << "if (!writefile(hf, (lpstr) hp, (int) cb, (lpdword) &dwtmp,null))" << endl; // close .bmp file. if (!closehandle(hf)) //errhandler("closehandle", hwnd); // free memory. globalfree((hglobal)lpbits); } int main() { cout << "screenshot - takes screen shot\nscreen shot put in clipboard" "\nthere 10 seconds before takes screen shot\n" << endl; string input; { cin >> input; if(input == "screenshot") { /*for(int i=1; i<11; i++) { sleep(1000); cout << << endl; if(i == 10) { break; } }*/ getscreenshot(); pbitmapinfo pbmi = createbitmapinfostruct(hbitmap); createbmpfile("c:\\users\\owner\\desktop\\bitmap.bmp", pbmi, hbitmap, hscreen); cout << "screenshot taken!" << endl; cin.ignore(2); sleep(3000); break; } else { cout << "invalid command." << endl; } } while(true); return 0; }
passing uninitialized values getbitmapdimensionex , getbitmapbits doesn't seems good, delete them since doesn't seem used.
void getscreenshot(void) { int x1, y1, x2, y2, w, h; // screen dimensions x1 = getsystemmetrics(sm_xvirtualscreen); x2 = getsystemmetrics(sm_cxvirtualscreen); y1 = getsystemmetrics(sm_yvirtualscreen); y2 = getsystemmetrics(sm_cyvirtualscreen); w = x2-x1; h = y2-y1; // copy screen bitmap hscreen = getdc(null); hdc hdc = createcompatibledc(hscreen); hbitmap = createcompatiblebitmap(hscreen, w, h); hgdiobj old_obj = selectobject(hdc, hbitmap); bool bret = bitblt(hdc, 0, 0, w, h, hscreen, x1, y1, srccopy); // save bitmap clipboard openclipboard(null); emptyclipboard(); setclipboarddata(cf_bitmap, hbitmap); closeclipboard(); // clean selectobject(hdc, old_obj); /*deletedc(hdc); releasedc(null, hscreen); deleteobject(hbitmap);*/ } then, set hdr.bftype hf != invalid_handle_value.
change
if (hf == invalid_handle_value) //errhandler("createfile", hwnd); hdr.bftype = 0x4d42; // 0x42 = "b" 0x4d = "m" to
if (hf == invalid_handle_value) { //errhandler("createfile", hwnd); } hdr.bftype = 0x4d42; // 0x42 = "b" 0x4d = "m" (add braces)
using lpctstr instead of lptstr type of pszfile, argument of createbmpfile avoid compiler warning when string literal passed.
Comments
Post a Comment