C++保存HBITMAP为位图文件的实现方法
程序员文章站
2022-03-27 08:45:28
本文使用c++将位图句柄hbitmap保存为位图文件,配合c++抓图代码可以实现抓图保存文件(.bmp)。其步骤如下:1、创建位图文件;2、计算位图中每个像素所占字节数;3. 获取位图结构bitmap...
本文使用c++将位图句柄hbitmap保存为位图文件,配合c++抓图代码可以实现抓图保存文件(.bmp)。
其步骤如下:
1、创建位图文件;
2、计算位图中每个像素所占字节数;
3. 获取位图结构bitmap;
4、构造位图信息头bitmapinfoheader;
5、构造位图文件头bitmapfileheader;
6、为位图内容分配内存;
7、处理调色板;
8、写入文件;
9、清除资源。
下面是c++源代码:
imagehelper.h
#pragma once #include <windows.h> #include <string> using namespace std; class imagehelper { public: static bool savebitmaptofile(hbitmap bitmap, const string& filename); //保存位图到文件 private: static word getbitmapbitcount(); //计算位图文件每个像素所占字节数 static void processpalette(hbitmap hbitmap, const bitmap& bitmap, dword palettesize, lpbitmapinfoheader lpbmpinfoheader); //处理调色板 };
imagehelper.cpp
#include "imagehelper.h" #include <shlwapi.h> bool imagehelper::savebitmaptofile(hbitmap hbitmap, const string& filename) { //1. 创建位图文件 const auto file = createfilea(filename.c_str(), generic_write, 0, nullptr, create_always, file_attribute_normal | file_flag_sequential_scan, nullptr); if (file == invalid_handle_value) { return false; } //2. 计算位图文件每个像素所占字节数 const auto bitcount = getbitmapbitcount(); //3. 获取位图结构 bitmap bitmap; ::getobject(hbitmap, sizeof(bitmap), reinterpret_cast<lpstr>(&bitmap)); //位图中像素字节大小(32字节对齐) const dword bmbitssize = ((bitmap.bmwidth * bitcount + 31) / 32) * 4 * bitmap.bmheight; //调色板大小 const dword palettesize = 0; //4. 构造位图信息头 bitmapinfoheader bmpinfoheader; //位图信息头结构 bmpinfoheader.bisize = sizeof(bitmapinfoheader); bmpinfoheader.biwidth = bitmap.bmwidth; bmpinfoheader.biheight = bitmap.bmheight; bmpinfoheader.biplanes = 1; bmpinfoheader.bibitcount = bitcount; bmpinfoheader.bicompression = bi_rgb; bmpinfoheader.bisizeimage = 0; bmpinfoheader.bixpelspermeter = 0; bmpinfoheader.biypelspermeter = 0; bmpinfoheader.biclrimportant = 0; bmpinfoheader.biclrused = 0; //5. 构造位图文件头 bitmapfileheader bmpfileheader; bmpfileheader.bftype = 0x4d42; //"bm" //位图文件大小 const dword dibsize = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader) + palettesize + bmbitssize; bmpfileheader.bfsize = dibsize; bmpfileheader.bfreserved1 = 0; bmpfileheader.bfreserved2 = 0; bmpfileheader.bfoffbits = static_cast<dword>(sizeof(bitmapfileheader)) + static_cast<dword>(sizeof(bitmapinfoheader)) + palettesize; //6. 为位图内容分配内存 const auto dib = globalalloc(ghnd, bmbitssize + palettesize + sizeof(bitmapinfoheader)); //内存句柄 const auto lpbmpinfoheader = static_cast<lpbitmapinfoheader>(globallock(dib)); //指向位图信息头结构 *lpbmpinfoheader = bmpinfoheader; //7. 处理调色板 processpalette(hbitmap, bitmap, palettesize, lpbmpinfoheader); //8. 写入文件 dword written = 0; //写入文件字节数 writefile(file, reinterpret_cast<lpstr>(&bmpfileheader), sizeof(bitmapfileheader), &written, nullptr); //写入位图文件头 writefile(file, reinterpret_cast<lpstr>(lpbmpinfoheader), dibsize, &written, nullptr); //写入位图文件其余内容 //9. 清理资源 globalunlock(dib); globalfree(dib); closehandle(file); return true; } //计算位图文件每个像素所占字节数 word imagehelper::getbitmapbitcount() { const auto dc = ::createdca("display", nullptr, nullptr, nullptr); //当前分辨率下每像素所占字节数 const auto bits = ::getdevicecaps(dc, bitspixel) * getdevicecaps(dc, planes); ::deletedc(dc); //位图中每像素所占字节数 word bitcount; if (bits <= 1) bitcount = 1; else if (bits <= 4) bitcount = 4; else if (bits <= 8) bitcount = 8; else bitcount = 24; return bitcount; } //处理调色板 void imagehelper::processpalette(hbitmap hbitmap, const bitmap& bitmap, dword palettesize, lpbitmapinfoheader lpbmpinfoheader) { handle oldpalette = nullptr; hdc dc = nullptr; const auto palette = getstockobject(default_palette); if (palette != nullptr) { dc = ::getdc(nullptr); oldpalette = ::selectpalette(dc, static_cast<hpalette>(palette), false); ::realizepalette(dc); //实现设备调色板 } //获取该调色板下新的像素值 getdibits(dc, hbitmap, 0, static_cast<uint>(bitmap.bmheight), reinterpret_cast<lpstr>(lpbmpinfoheader) + sizeof(bitmapinfoheader) + palettesize, reinterpret_cast<bitmapinfo*>(lpbmpinfoheader), dib_rgb_colors); //恢复调色板 if (oldpalette != nullptr) { ::selectpalette(dc, static_cast<hpalette>(oldpalette), true); ::realizepalette(dc); ::releasedc(nullptr, dc); } }
以上就是c++保存hbitmap为位图文件的实现方法的详细内容,更多关于c++保存hbitmap的资料请关注其它相关文章!
上一篇: [转载]让SQL运行得更快