簡體   English   中英

png 圖像的大小

[英]the size of a png image

例外是Unhandled exception at 0x770CAE54 (ntdll.dll) in OpenCVPaint.exe: 0xC0000374: A heap has been corrupted (parameters: 0x770DFE38). 堆中有一個Corruption ,因為我寫到一個我不應該寫的地方(我沒有分配足夠的空間)。 但是我怎么會寫到一個我不應該寫的地方呢?

我部分修復了它,我更改了代碼中的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;
}

請注意, GetDIBits函數要求圖像具有寬度為 DWORD 對齊的掃描線(必須是sizeof(DWORD)的倍數,對於 Window 的 DIB 為4 )。 從鏈接:

除 RLE 壓縮位圖外,掃描線必須在 DWORD 上對齊。

由於原始圖像具有未對齊的寬度,因此應用程序負責通過調整寬度計算來強制對齊。

當圖像未對齊,並且應用程序沒有設置對齊圖像時,通常最終發生的情況是:

1) 顯示圖像,但有“階梯”效果,顯示圖像的每條掃描線似乎偏離了一定量,或者,

2) 沒有分配足夠的內存來處理圖像,因此可能會出現堆錯誤。

問題似乎是在create函數中沒有為圖像分配足夠的內存來匹配對齊調整所需的額外字節。 因此,例如,如果寬度為 437,則計算分配內存量時使用的實際寬度應基於寬度 440,而不是 437。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM