首页 > 系统相关 >【小记】BITMAP To BMP 调用 GetDIBits 引发栈内存损坏问题

【小记】BITMAP To BMP 调用 GetDIBits 引发栈内存损坏问题

时间:2024-01-14 17:11:06浏览次数:26  
标签:bf return buffer bi bitmap BMP GetDIBits sizeof BITMAP

BITMAP bitmap;
if (!GetObject(hBitmap, sizeof(bitmap), &bitmap)) { // 外部传入 hBitmap
    return false;
}

// 创建位图信息头
BITMAPINFO bitInfo;
BITMAPINFOHEADER& bi = bitInfo.bmiHeader;
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bitmap.bmBitsPixel; // 这里为 8 位
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bi.biSize = sizeof(BITMAPINFOHEADER);

// 创建位图文件头
BITMAPFILEHEADER bf;
bf.bfType = 0x4D42;  // "BM"
bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bitmap.bmWidthBytes * bitmap.bmHeight;
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bf.bfReserved1 = 0;
bf.bfReserved2 = 0;

// 创建一个足够大的缓冲区来存储位图文件头、位图信息头和像素数据
bufferSize = bf.bfSize;
buffer = (unsigned char*)GlobalAlloc(GMEM_FIXED, bufferSize);
if (buffer == nullptr) {
    return false;
}

// 将位图文件头、位图信息头和像素数据复制到缓冲区 (或直接写入文件)
memcpy(buffer, &bf, sizeof(bf));
memcpy(buffer + sizeof(bf), &bi, sizeof(bi));

HDC hdc = CreateCompatibleDC(NULL);
if (hdc == NULL) {
    return false;
}

if (!GetDIBits(hdc, hBitmap, 0, (UINT)bitmap.bmHeight, buffer + bf.bfOffBits, &bitInfo, DIB_RGB_COLORS)) {
    GlobalFree(buffer);
    bufferSize = 0;
    return false;
}

DeleteObject(bitmap); 
ReleaseDC(hdc); 

return true;

 

太忙,简单说一下:

当 BMP 小于 16 位时,需要额外的内存空间来存储颜色数据。只传入一个 BITMAPINFOHEADER 是不行的,在 GetDIBits 调用后会引发栈内存损坏导致程序崩溃。需要传入一个完整的 BITMAPINFO 类型才行。

标签:bf,return,buffer,bi,bitmap,BMP,GetDIBits,sizeof,BITMAP
From: https://www.cnblogs.com/airchip/p/17963920

相关文章

  • Roaring bitmaps
    Roaringbitmaps最近看一篇文章,里面涉及到使用roaringbitmaps来推送用户广告并通过计算交集来降低用户广告推送次数。本文给出roaringbitmaps的原理和基本用法,后续给出原文的内容。本文来自:AprimeronRoaringbitmaps:whattheyareandhowtheywork目录Roaringbitmaps......
  • 关于Android图像Bitmap类你要知道的一切
    Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色值。Android中的Bitmap是用来表示图像的类,它可以用来加载、显示和处理图像。你可以通过Bitmap类来创建一个......
  • 【C#/WPF】Bitmap、BitmapImage、ImageSource 、byte[]转换问题
    C#/WPF项目中,用到图像相关的功能时,涉及到多种图像数据类型的相互转换问题,这里做了个整理。包含的内容如下:Bitmap和BitmapImage相互转换。RenderTargetBitmap–>BitmapImageImageSource–>BitmapBitmapImage和byte[]相互转换。byte[]–>BitmapStackOverflow上有很......
  • Wpf Bitmap(Image)Base64,Url,文件Path,Stream转BitmapSource(ImageSource),无需外部d
    直接上代码usingSystem;usingSystem.Drawing;usingSystem.IO;usingSystem.Windows.Forms;usingSystem.Windows.Media.Imaging;namespaceCommonUtils{///<summary>///Windows图片处理///</summary>publicstaticclassWindowsImage......
  • 通俗的理解Bitmap(位图)和RoaringBitmap(压缩位图)
    一、使用的场景日常业务中需要大量存储一些重复的字符串,例如每日签到用户、朋友圈点赞的好友、计算每日登录用户等。字符串无论长短不仅会浪费大量的存储资源,而且读取查询也耗时耗资源,那有没有一种存储方式对这一类场景进行优化呢。二、什么原理1、Bitmap如何解决这个问题拿每......
  • 无涯教程-MFC - Bitmap Button函数
    位图按钮在其脸上显示图片或图片和文本,这通常是为了使按钮略显,使用从CButton派生的CBitmapButton类创建位图按钮。这是CBitmapButton类中的方法的列表。Sr.No.Name&描述1AutoLoad将对话框中的按钮与CBitmapButton类的对象相关联,按名称加载位图,并调整按钮的大小以适合位......
  • 常见场景题-Redis的bitmap如何实现签到功能?
    Redis的bitmap实现签到系统?答:主要讲一下Redis原生的bitmap的使用方法,以及如何使用bitmap来实现签到功能先来看一下如何使用redisbitmap的原生命令实现签到功能:签到我们先来设计key:userid:yyyyMM,那么假如usera在2023年10月3日和2023年10月4日签到的话,使用以下命令:se......
  • Halcon 与 bitmap 互转
     Halcon与bitmap互转:publicvoidBitmap2HObjectBpp24(Bitmapbmp,outHObjectimage){try{Rectanglerect=newRectangle(0,0,bmp.Width,bmp.Height);BitmapDatasrcBmpData=bmp.......
  • OpenCV Mat和Bitmap的转换
    最常用的方式是:Cv2.ImRead()可以将位图文件转成Mat数据格式Cv2.ImWrite()可以将Mat数据格式保存到位图文件.不通过读写文件作为转换介质的方法:privatevoidtestMatToPicture(){varmat=Cv2.ImRead("D:\\my_workspace\\opencv\\images\\lena.jpg",ImreadModes.Co......
  • MPV进阶使用:LIBMPV
    一、介绍mpv不仅提供了IPC的使用方式,还提供了函数库,方便将mpv嵌入其他程序。EMBEDDINGINTOOTHERPROGRAMS(LIBMPV)mpvcanbeembeddedintootherprogramsasvideo/audioplaybackbackend.Therecommendedwaytodosoisusinglibmpv.Seelibmpv/client.hinthe......