0

我正在尝试将标准的 24 位 BMP 文件读入字节数组,以便我可以将该字节数组发送到 libpng 以保存为 png。我的代码,编译:

#include <string>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <Windows.h>
#include "png.h"

using namespace std;

namespace BMP2PNG {
long getFileSize(FILE *file)
    {
        long lCurPos, lEndPos;
        lCurPos = ftell(file);
        fseek(file, 0, 2);
        lEndPos = ftell(file);
        fseek(file, lCurPos, 0);
        return lEndPos;
    }


private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
         {
             std::string filenamePNG = "D:\\TEST.png";
             FILE *fp = fopen(filenamePNG.c_str(), "wb");

             png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);

             png_info *info_ptr = png_create_info_struct(png_ptr);

             png_init_io(png_ptr, fp);

             png_set_IHDR(png_ptr,info_ptr,1920,1080,16,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);

             png_write_info(png_ptr,info_ptr);
             png_set_swap(png_ptr);

             const char *inputImage = "G:\\R-000.bmp";
             BYTE *fileBuf;
             BYTE *noHeaderBuf;
             FILE *inFile = NULL;

             inFile = fopen(inputImage, "rb");

             long fileSize = getFileSize(inFile);

             fileBuf = new BYTE[fileSize];
             noHeaderBuf = new BYTE[fileSize - 54];

             fread(fileBuf,fileSize,1,inFile);

             for(int i = 54; i < fileSize; i++) //gets rid of 54-byte bmp header
             {
                noHeaderBuf[i-54] = fileBuf[i];
             }

             fclose(inFile);

             png_write_rows(png_ptr, (png_bytep*)&noHeaderBuf, 1);

             png_write_end(png_ptr, NULL);

             fclose(fp);
         }
};

不幸的是,当我单击运行代码的按钮时,出现错误“尝试读取或写入受保护的内存...”。我对 C++ 很陌生,但我认为我正确地读取了文件。为什么会发生这种情况,我该如何解决?

此外,我的最终目标是一次读取一个像素行的 BMP,这样我就不会使用太多内存。如果 BMP 是 1920x1080,我只需要为每行读取 1920 x 3 个字节。我将如何一次将文件读入字节数组 n 个字节?

4

3 回答 3

0

You are reading filee size of your *.bmp file, but "real" data can be larger. BMP can have compression (RLE). After that when you write decompressed PNG to that array, you can have overflow size of image, because you previsouly obtained size of compressed BMP file.

于 2013-03-31T12:08:43.383 回答
0

在功能

png_set_IHDR(png_ptr,info_ptr,1920,1080,16,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);

为什么将位深度设置为 16 ?不应该是 8,因为 BMP 的每个 RGB 通道都是 8 位的。

同样对于 PNG 处理,我正在使用这个库: http: //lodev.org/lodepng/。它工作正常。

于 2013-04-01T08:47:33.993 回答
0

您的getFileSize()方法实际上并没有返回文件大小。您基本上移动到 BMP 标头中的正确位置,但不是实际读取表示大小的下 4 个字节,而是返回文件中的位置(始终为 2)。然后在调用函数中,您没有任何错误检查,并且您的代码假定文件大小始终大于 54(例如,读取缓冲区的分配)。

另请记住,BMP 标头中的文件大小字段可能并不总是正确的,您还应该考虑实际文件大小。

于 2013-03-31T10:13:08.657 回答