C 不读取整个 BMP 文件 - fopen
C not reading entire BMP file - fopen
所以我正在尝试读取 C 中的 .bmp 文件。稍后我将使用 openssl 库加密该文件 - 但这只是背景信息。
我需要以二进制模式打开文件(显然),但无论出于何种原因,当我尝试打开文件时,它只读取 4 个字节。当我尝试输出我刚刚打开的这个确切文件(用于错误测试)时,它输出以下内容 - 88 24 AD FB
.
在我的故障排除中,我决定在文本文件(54 字节)上尝试这个,我得到了完全相同的结果。
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
char * fileName="pic_original.bmp";
//read the file from given filename in binary mode
printf("Start to read the .bmp file \n");
FILE *image;
image = fopen(fileName,"rb");
//print the size of the image (4 bytes every damn time)
printf("Size of image: %d\n",sizeof(image));
//output the exact file that was read (error testing)
FILE *test;
test = fopen("./test.bin", "w");
fwrite(image, sizeof(image), 1, test);
fclose(test);
fclose(image);
return 1;
}
这是图像(出于某种原因以 png 格式上传)
不太确定我哪里出错了,但我在 C 语言方面不是很熟练。
干杯,
利亚姆
编辑 1:
//allocate memory for the header and image
char *headerBuf = (char *)malloc(54);
char *imageBuf = (char *)malloc(sizeof(image)-54); //this line is wrong - thanks to user EOF
//allocate memory for the final ciphertext
char *imagecipherCBC = (char *)malloc(sizeof(image)); //wrong also
//read first 54 bytes (header)
rewind(image);
fread(headerBuf,54,1,image);
//read the bitmap image until the end of the file
fread(imageBuf,sizeof(image),1,image); //also wrong
如果您的目标是加密文件,则将整个文件读入缓冲区,对其进行加密,然后将其保存为二进制文件。您可以通过将文件指针移动到末尾来找到文件大小。示例:
int main()
{
FILE *fin;
fin = fopen("pic_original.bmp", "rb");
fseek(fin, 0, SEEK_END);
int filesize = ftell(fin);
rewind(fin);
char *buf = malloc(filesize);
fread(buf, 1, filesize, fin);
fclose(fin);
//encrypt the buffer...
FILE *fout = fopen("output.bmp", "wb");
fwrite(buf, 1, filesize, fout);
fclose(fout);
return 0;
}
这适用于任何文件。 OpenSSL已经有直接加密文件的功能
如果出于某种原因你想保持 header 不变,并且只更改后面的位,那么请单独阅读 header:
int main()
{
FILE *fin = fopen("input.bmp", "rb");
if(!fin) { printf("cannot open input\n"); return 0; }
FILE *fout = fopen("output.bmp", "wb");
if(!fout) { printf("cannot open output\n"); return 0; }
fseek(fin, 0, SEEK_END);
int filesize = ftell(fin);
if(filesize <= 54)
{
printf("wrong filesize\n");
return 0;
}
rewind(fin);
char *header = malloc(54);
char *buf = malloc(filesize - 54);
//encrypt buf...
fread(header, 1, 54, fin);
fread(buf, 1, filesize - 54, fin);
fclose(fin);
fwrite(header, 1, 54, fout);
fwrite(buf, 1, filesize - 54, fout);
fclose(fout);
free(header);
free(buf);
return 0;
}
我想这样做的好处是加密位图仍会被识别为位图。但是只有加密方法不会向输出添加额外的字节。
请注意,8 位、4 位和单色位图有一个调色板,它位于 54 字节标题之后,然后是图像位。
嗯,
图像的大小当然是 4 个字节,这是 32 位机器上的文件指针。
我想你必须准备一些bmp文件的图像缓冲区作为一个简单的例子,然后如果你的文件不是太大,你可以对这个图像缓冲区的内容进行加密和解密。
static void read_from_image(char *imageBuf, int fileLength)
{
const char * outFileName="c:/DEV/temp/test.bin";
char headerBuf[54];
char *imagecipherCBC;
FILE *test;
test = fopen(outFileName, "wb");
//allocate memory for the final ciphertext
imagecipherCBC = (char *)malloc(fileLength *sizeof(char));
//read first 54 bytes (header)
//fread(headerBuf,54,1,image);
memcpy(headerBuf, imageBuf, 54 * sizeof(char));
//read the bitmap image until the end of the file
//fread(imageBuf,sizeof(image),1,image); //also wrong
fwrite(imageBuf, fileLength * sizeof(char), 1, test);
fflush(test);
fclose(test);
free(imagecipherCBC),imagecipherCBC = NULL;
free(imageBuf),imageBuf = NULL;
return;
}
您可以在主函数中设置文件长度和图像缓冲区。
int main(int argc, char *argv[])
{
const char * fileName="c:/DEV/temp/pic_original.bmp";
int fileLength = 0;
FILE *image;
char *imageBuffer;
imageBuffer = NULL;
image = fopen(fileName,"rb");
printf("read the file from given filename in binary mode \n");
printf("Start to read the .bmp file \n");
//try to get a file length;
fseek(image, 0, SEEK_END);
fileLength = ftell(image);
fseek(image, 0, SEEK_SET);
rewind(image);
imageBuffer = (char*)malloc(fileLength * sizeof(char));
//print the size of the image (4 bytes every damn time)
printf("read the file from given filename in binary mode \n");
printf("Size of image file pointer: %d\n",sizeof(image));
printf("Size of image: %d\n",fileLength);
//output the exact file that was read (error testing)
fread(imageBuffer,sizeof(char),fileLength*sizeof(char), image);
fclose(image);
read_from_image(imageBuffer, fileLength);
return 0;
}
祝你好运
所以我正在尝试读取 C 中的 .bmp 文件。稍后我将使用 openssl 库加密该文件 - 但这只是背景信息。
我需要以二进制模式打开文件(显然),但无论出于何种原因,当我尝试打开文件时,它只读取 4 个字节。当我尝试输出我刚刚打开的这个确切文件(用于错误测试)时,它输出以下内容 - 88 24 AD FB
.
在我的故障排除中,我决定在文本文件(54 字节)上尝试这个,我得到了完全相同的结果。
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
char * fileName="pic_original.bmp";
//read the file from given filename in binary mode
printf("Start to read the .bmp file \n");
FILE *image;
image = fopen(fileName,"rb");
//print the size of the image (4 bytes every damn time)
printf("Size of image: %d\n",sizeof(image));
//output the exact file that was read (error testing)
FILE *test;
test = fopen("./test.bin", "w");
fwrite(image, sizeof(image), 1, test);
fclose(test);
fclose(image);
return 1;
}
这是图像(出于某种原因以 png 格式上传)
不太确定我哪里出错了,但我在 C 语言方面不是很熟练。
干杯, 利亚姆
编辑 1:
//allocate memory for the header and image
char *headerBuf = (char *)malloc(54);
char *imageBuf = (char *)malloc(sizeof(image)-54); //this line is wrong - thanks to user EOF
//allocate memory for the final ciphertext
char *imagecipherCBC = (char *)malloc(sizeof(image)); //wrong also
//read first 54 bytes (header)
rewind(image);
fread(headerBuf,54,1,image);
//read the bitmap image until the end of the file
fread(imageBuf,sizeof(image),1,image); //also wrong
如果您的目标是加密文件,则将整个文件读入缓冲区,对其进行加密,然后将其保存为二进制文件。您可以通过将文件指针移动到末尾来找到文件大小。示例:
int main()
{
FILE *fin;
fin = fopen("pic_original.bmp", "rb");
fseek(fin, 0, SEEK_END);
int filesize = ftell(fin);
rewind(fin);
char *buf = malloc(filesize);
fread(buf, 1, filesize, fin);
fclose(fin);
//encrypt the buffer...
FILE *fout = fopen("output.bmp", "wb");
fwrite(buf, 1, filesize, fout);
fclose(fout);
return 0;
}
这适用于任何文件。 OpenSSL已经有直接加密文件的功能
如果出于某种原因你想保持 header 不变,并且只更改后面的位,那么请单独阅读 header:
int main()
{
FILE *fin = fopen("input.bmp", "rb");
if(!fin) { printf("cannot open input\n"); return 0; }
FILE *fout = fopen("output.bmp", "wb");
if(!fout) { printf("cannot open output\n"); return 0; }
fseek(fin, 0, SEEK_END);
int filesize = ftell(fin);
if(filesize <= 54)
{
printf("wrong filesize\n");
return 0;
}
rewind(fin);
char *header = malloc(54);
char *buf = malloc(filesize - 54);
//encrypt buf...
fread(header, 1, 54, fin);
fread(buf, 1, filesize - 54, fin);
fclose(fin);
fwrite(header, 1, 54, fout);
fwrite(buf, 1, filesize - 54, fout);
fclose(fout);
free(header);
free(buf);
return 0;
}
我想这样做的好处是加密位图仍会被识别为位图。但是只有加密方法不会向输出添加额外的字节。
请注意,8 位、4 位和单色位图有一个调色板,它位于 54 字节标题之后,然后是图像位。
嗯, 图像的大小当然是 4 个字节,这是 32 位机器上的文件指针。
我想你必须准备一些bmp文件的图像缓冲区作为一个简单的例子,然后如果你的文件不是太大,你可以对这个图像缓冲区的内容进行加密和解密。
static void read_from_image(char *imageBuf, int fileLength)
{
const char * outFileName="c:/DEV/temp/test.bin";
char headerBuf[54];
char *imagecipherCBC;
FILE *test;
test = fopen(outFileName, "wb");
//allocate memory for the final ciphertext
imagecipherCBC = (char *)malloc(fileLength *sizeof(char));
//read first 54 bytes (header)
//fread(headerBuf,54,1,image);
memcpy(headerBuf, imageBuf, 54 * sizeof(char));
//read the bitmap image until the end of the file
//fread(imageBuf,sizeof(image),1,image); //also wrong
fwrite(imageBuf, fileLength * sizeof(char), 1, test);
fflush(test);
fclose(test);
free(imagecipherCBC),imagecipherCBC = NULL;
free(imageBuf),imageBuf = NULL;
return;
}
您可以在主函数中设置文件长度和图像缓冲区。
int main(int argc, char *argv[])
{
const char * fileName="c:/DEV/temp/pic_original.bmp";
int fileLength = 0;
FILE *image;
char *imageBuffer;
imageBuffer = NULL;
image = fopen(fileName,"rb");
printf("read the file from given filename in binary mode \n");
printf("Start to read the .bmp file \n");
//try to get a file length;
fseek(image, 0, SEEK_END);
fileLength = ftell(image);
fseek(image, 0, SEEK_SET);
rewind(image);
imageBuffer = (char*)malloc(fileLength * sizeof(char));
//print the size of the image (4 bytes every damn time)
printf("read the file from given filename in binary mode \n");
printf("Size of image file pointer: %d\n",sizeof(image));
printf("Size of image: %d\n",fileLength);
//output the exact file that was read (error testing)
fread(imageBuffer,sizeof(char),fileLength*sizeof(char), image);
fclose(image);
read_from_image(imageBuffer, fileLength);
return 0;
}
祝你好运