当前正在使用VC ++处理打开/读取图像。

我在互联网上遇到的一些示例使用Windows.h I / O例程,如ReadFile ...,但是那里的声明似乎不一致。 (并不是说我在挑战Windows ..也许我不了解)

这就是我所得到的。

//So i have this function to load file
BYTE* LoadFile ( int* width, int* height, long* size, LPCWSTR bmpfile )
{
  BITMAPFILEHEADER bmpheader;
  BITMAPINFOHEADER bmpinfo;
  DWORD bytesread = 0;
      HANDLE file = CreateFile ( bmpfile , GENERIC_READ, FILE_SHARE_READ,NULL,
                              OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
  if ( NULL == file )
    return NULL;

  if ( ReadFile ( file, &bmpheader, sizeof ( BITMAPFILEHEADER ),&bytesread,
                      NULL ) == false )
  {
    CloseHandle ( file );
    return NULL;
  }
 .
 .
 .
 return appropriate value;
}


现在,在WinBase.h中声明ReadFile API函数如下

WINBASEAPI BOOL WINAPI ReadFile(
  _In_         HANDLE hFile,
  _Out_        LPVOID lpBuffer,
  _In_         DWORD nNumberOfBytesToRead,
  _Out_opt_    LPDWORD lpNumberOfBytesRead,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);


在MSDN示例中...
他们这样称呼这个功能。

ReadFile(hFile, chBuffer, BUFSIZE, &dwBytesRead, NULL)


期望“ bytesRead”是out参数。因此它给了我读取的字节数。

但是在我的代码中..它给出了错误信息。
    'ReadFile':无法将参数4从'LPDWORD *'转换为'LPDWORD'

所以我只是将bytesRead初始化为0并按值传递。(这是错误的..只是为了检查它是否有效)。

那么它给出了这个例外

Unhandled exception at 0x774406ae in ImProc.exe: 0xC0000005: Access violation
writing location 0x00000000.


请提示。

请告诉我是否错过了任何代码...。包括在形成问题本身时。

谢谢。

最佳答案

LPDWORD bytesread = 0更改为DWORD bytesread = 0

我使用以下代码运行您的代码:

#include <windows.h>
#include <cstdio>

BYTE* LoadFile(int* width, int* height, long* size, LPCWSTR bmpfile)
{
    DWORD bytesread = 0;
    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;

    HANDLE file = CreateFile(bmpfile , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (file == NULL)
        return NULL;

    if (ReadFile(file, &bmpheader, sizeof(BITMAPFILEHEADER), &bytesread, NULL) == FALSE)
    {
        CloseHandle(file);
        return NULL;
    }

    printf("Bytes Read: %d", bytesread);
    CloseHandle(file);
    return NULL;
}

int main()
{
    int width = 0;
    int height = 0;
    long size = 0;

    LoadFile(&width, &height, &size, L"C:/Users/Brandon/Desktop/Foo.bmp");
}


列印14。

但是,如果您想要更便携的解决方案,那么以下内容也可以为您服务吗?

位图.h:

#ifndef BITMAP_H_INCLUDED
#define BITMAP_H_INCLUDED

#include <iostream>
#include <fstream>
#include <vector>
#include <stdexcept>

class Bitmap
{
    private:
        std::vector<std::uint8_t> Pixels;
        std::uint32_t width, height;
        std::uint16_t BitsPerPixel;

    public:
        Bitmap(const char* FilePath);
        void Save(const char* FilePath);
};
#endif // BITMAP_H_INCLUDED


位图.cpp:

Bitmap::Bitmap(const char* FilePath) : Pixels(0), width(0), height(0), BitsPerPixel(0)
{
    std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
    if (!hFile.is_open()) throw std::invalid_argument("Error: File Not Found.");

    hFile.seekg(0, std::ios::end);
    int Length = hFile.tellg();
    hFile.seekg(0, std::ios::beg);
    std::vector<std::uint8_t> FileInfo(Length);
    hFile.read(reinterpret_cast<char*>(FileInfo.data()), 54);

    if(FileInfo[0] != 'B' && FileInfo[1] != 'M')
    {
        hFile.close();
        throw std::invalid_argument("Error: Invalid File Format. Bitmap Required.");
    }

    if (FileInfo[28] != 24 || FileInfo[28] != 32)
    {
        hFile.close();
        throw std::invalid_argument("Error: Invalid File Format. 24 or 32 bit Image Required.");
    }

    BitsPerPixel = FileInfo[28];
    width = FileInfo[18] + (FileInfo[19] << 8);
    height = FileInfo[22] + (FileInfo[23] << 8);
    std::uint32_t PixelsOffset = FileInfo[10] + (FileInfo[11] << 8);
    std::uint32_t size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
    Pixels.resize(size);

    hFile.seekg (PixelsOffset, std::ios::beg);
    hFile.read(reinterpret_cast<char*>(Pixels.data()), size);
    hFile.close();
}

void Bitmap::Save(const char* FilePath)
{
    std::fstream hFile(FilePath, std::ios::out | std::ios::binary);
    if (!hFile.is_open()) throw std::invalid_argument("Error: File not found.");

    std::uint32_t Trash = 0;
    std::uint16_t Planes = 1;
    std::uint32_t biSize = 40;
    std::uint16_t Type = 0x4D42;
    std::uint32_t compression = 0;
    std::uint32_t PixelsOffsetBits = 54;
    std::uint32_t size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
    std::uint32_t bfSize = 54 + size;

    hFile.write(reinterpret_cast<char*>(&Type), sizeof(Type));
    hFile.write(reinterpret_cast<char*>(&bfSize), sizeof(bfSize));
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(std::uint32_t));
    hFile.write(reinterpret_cast<char*>(&PixelsOffsetBits), sizeof(PixelsOffsetBits));
    hFile.write(reinterpret_cast<char*>(&biSize), sizeof(biSize));
    hFile.write(reinterpret_cast<char*>(&width), sizeof(width));
    hFile.write(reinterpret_cast<char*>(&height), sizeof(height));
    hFile.write(reinterpret_cast<char*>(&Planes), sizeof(Planes));
    hFile.write(reinterpret_cast<char*>(&BitsPerPixel), sizeof(BitsPerPixel));
    hFile.write(reinterpret_cast<char*>(&compression), sizeof(compression));
    hFile.write(reinterpret_cast<char*>(&size), sizeof(size));
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(std::uint32_t));
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(std::uint32_t));
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(std::uint32_t));
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(std::uint32_t));
    hFile.write(reinterpret_cast<char*>(Pixels.data()), size);
    hFile.close();
}

08-18 10:12