2015-12-22 3 views
-4

Исключение составляет Unhandled exception at 0x770CAE54 (ntdll.dll) in OpenCVPaint.exe: 0xC0000374: A heap has been corrupted (parameters: 0x770DFE38). Существует Коррупция в куче, потому что я пишу в место, которое я не должен (я не выделял достаточно места). Но почему я пишу туда, где не должен?размер png изображения

Я исправил его частично, я изменил my_pic.create() строк и столбцов в коде, так что хватит, я думаю. Но зачем мне это нужно? Почему это пошло не так с h как 67 и w как 73 (именно то, что это должно было понадобиться)? Сколько памяти нужно, если нет 67(HEIGHT)x73(WIDTH)x3(RGB)?

  • Если изменить тип (в настоящее время CV_8UC3 он работает, но изображение, захваченное далеко точного), а не создающая линии, она тоже работает.

  • bmi.biImageSize` рассчитывается как 67, почему? это вызывает проблему?

Код выглядит следующим образом:

#include <opencv2\opencv.hpp> 
#include <Windows.h> 

using namespace cv; 

Mat screenCapture() 
{ 
     HDC hdcSource = GetDC(NULL); 
     HDC hdcMemory = CreateCompatibleDC(hdcSource); 


    Mat my_pic; 
    int i, j; 
    int w, h; 
    POINT p1, p2; //Windows.h 

    p1.x = 437; 
    p1.y = 247; 
    p2.x = 510; 
    p2.y = 314; 

    w = p2.x - p1.x; 
    h = p2.y - p1.y; 

    HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h); 
    HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap); 
    BITMAPINFOHEADER bmi = { 0 }; 
    bmi.biSize = sizeof(BITMAPINFOHEADER); 
    bmi.biPlanes = 1; 
    bmi.biBitCount = 24; 

    bmi.biWidth = w; 
    bmi.biHeight = -h; 
    bmi.biCompression = BI_RGB; 

    bmi.biSizeImage = ((bmi.biWidth * bmi.biBitCount + 31) & ~31)/8 * bmi.biHeight<0 ? -bmi.biHeight : bmi.biHeight; 
    bmi.biXPelsPerMeter = 0; 
    bmi.biYPelsPerMeter = 0; 
    bmi.biClrImportant = 0; 
    bmi.biClrUsed = 256; 

    while (!(BitBlt(hdcMemory, 0, 0, w, h, hdcSource, p1.x, p1.y, SRCCOPY))); 

    while (!(hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld))); 

    my_pic.create(h, w, CV_8UC3); //THE PROBLEM IS HERE, NOT ENOUGH ALLOCATED 

    while (!(GetDIBits(hdcSource, hBitmap, 0, h, my_pic.data, (BITMAPINFO*)&bmi, DIB_RGB_COLORS))); 

    DeleteDC(hdcSource); 
    DeleteDC(hdcMemory); 

    return my_pic; 
} 

int main() 
{ 
    Mat img = screenCapture(); 
    malloc(0); //exception occurs here 

    return 0; 
} 
+0

Было бы очень признательно, если бы вы упоминали причина того, почему вы проголосовали за этот вопрос. – Jim

+5

Он занижен, потому что вы не предоставили код для воспроизведения вашей проблемы. Я этого не делал, но большинство людей, которые хотят помочь, также хотят увидеть запущенный пример. – nicomp

+1

Пожалуйста, напишите несколько [Минимальный, полный и проверенный пример] (https://stackoverflow.com/help/mcve) код. И я проголосовал. Если вы это сделаете, отмените вниз голос. –

ответ

0

Обратите внимание, что функция GetDIBits требует, чтобы образы сканирования линий, которые имеют ширину, которые DWORD выровнены (должно быть кратно sizeof(DWORD), который 4 для DIB окна). Из ссылки:

Строки сканирования должны быть выровнены по DWORD, за исключением сжатых растровых изображений RLE.

Поскольку исходное изображение имеет ширину, которая не выровнена, приложение должно принудительно выравнивать, регулируя вычисление ширины.

Когда изображение не выровнены, и никакие положения не выполняются приложением для выравнивания изображения, что обычно заканчивается происходит либо:

1) Изображение отображается, но имеет эффект «лестница» , где каждая строка развертки отображаемого изображения, кажется, отключена на определенную сумму или

2) Недостаточно памяти для обработки изображения, и, следовательно, могут возникать ошибки кучи.

Проблема заключается в том, что недостаточно памяти для изображения в функции create, чтобы соответствовать дополнительным байтам, необходимым для корректировки выравнивания. Например, если ширина равна 437, фактическая ширина, используемая при расчете объема памяти для распределения, должна быть основана на ширине 440, а не 437.

Смежные вопросы