【发布时间】:2013-03-31 09:52:11
【问题描述】:
我正在尝试将标准 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 个字节?
【问题讨论】:
-
没有错误检查 -
fopen调用成功了吗? -
而不是 fseek(file, 0, 2) 中的“通配符”,您应该使用 fseek(file, 0, SEEK_END)。 SEEK_SET 和第三个 SEKK_ 也是如此。它的可读性更高,而不是代码不那么混乱。
-
您显然在使用 C++/CLI。我不确定您使用的是 WinForms 还是 WPF。如果您是 C++ 新手,这可能不是最好的起点。您最好使用 C# 并使用 .NET 框架的工具来转换您的图像。看看stackoverflow.com/questions/1060442/png-to-bmp。我知道您正在以另一种方式进行转换,但它同样简单。
-
@suspectus- 是的 fopen 调用成功,我只是无法读取文件。 @ ferruccio-我只是将 Visual C++ Express 与 Windows 窗体应用程序一起使用。如果可以的话,我绝对会使用 C#,因为我在这方面有更多经验,但是 libpng 仅针对 C 和 C++ 编写(当然,除非你可以告诉我如何在 C# 中使用 .lib 和 .h 文件)。我已经尝试过 .NET BMPEncoder 的东西,但它不能正确保存 PNG 文件,而且由于内存限制,我需要能够一次完成这一行。
-
如果出现错误,您是否尝试在调试器中运行代码,查看错误发生在哪里?你对错误的定义有点模糊。