Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中读取/写入.bmp文件时出现问题_C_Image Processing - Fatal编程技术网

在C中读取/写入.bmp文件时出现问题

在C中读取/写入.bmp文件时出现问题,c,image-processing,C,Image Processing,我的程序需要能够读取.bmp图像,在其中写入一些数据,然后创建另一个.bmp图像。首先,我开始编写一些东西来读取图像,然后在另一个文件中重写相同的图像,但我遇到了一些问题。 这是我的密码: bmp.h: #ifndef _BMP_H_ #define _BMP_H_ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #inclu

我的程序需要能够读取.bmp图像,在其中写入一些数据,然后创建另一个.bmp图像。首先,我开始编写一些东西来读取图像,然后在另一个文件中重写相同的图像,但我遇到了一些问题。 这是我的密码:

bmp.h:

#ifndef _BMP_H_
#define _BMP_H_


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

#pragma pack(push, 1)
typedef struct {
  uint16_t type;
  uint32_t fileSize;
  uint16_t reserved1;
  uint16_t reserved2;
  uint32_t offset;
} BMP_File_Header;

typedef struct {
  BMP_File_Header fileHeader;
  uint32_t bSize;
  int32_t width;
  int32_t height;
  uint16_t planes;
  uint16_t bitCount;
  uint32_t compression;
  uint32_t imageSize;
  int32_t xPixelsPerMeter;
  int32_t yPixelsPerMeter;
  uint32_t colorUsed;
  uint32_t importantColor;
} BMP_Info_Header;
#pragma pack(pop)

BMP_Info_Header* loadBMP(const char *filename, char *data);
void writeBMP(BMP_Info_Header *infoHeader, char *data);

#endif
\ifndef\u BMP\u H_
#定义_
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#pragma包(推送,1)
类型定义结构{
uint16_t型;
uint32_t文件大小;
uint16保留1;
uint16_t储备2;
uint32_t偏移量;
}BMP_文件_头;
类型定义结构{
BMP_文件头文件头;
uint32_t b尺寸;
int32_t宽度;
int32_t高度;
uint16_t平面;
uint16_t比特计数;
uint32_t压缩;
uint32_t图像大小;
int32_t xPixelsPerMeter;
int32_t型验光仪;
使用uint32_t颜色;
uint32_t重要颜色;
}BMP_信息_标题;
#布拉格语包(流行语)
BMP_Info_Header*loadBMP(常量字符*文件名,字符*数据);
void writeBMP(BMP\u Info\u Header*infoHeader,char*data);
#恩迪夫
bmp.c:

#include "bmp.h"


BMP_Info_Header* loadBMP(const char *file_name, char *data) {
  FILE *file;
  BMP_Info_Header *infoHeader;
  int n;

  //Open the file
  file = fopen(file_name, "rb");
  if (!file) {
    fprintf(stderr, "Failed to read file %s.\n", file_name);
    exit(1);
  }

  //Alloc and read the headers
  infoHeader = (BMP_Info_Header *) malloc (sizeof(BMP_Info_Header));

  n = fread(infoHeader, sizeof(BMP_Info_Header), 1, file);

  //Check format
  if (infoHeader->fileHeader.type != 0x4D42) {
    fclose(file);
    fprintf(stderr, "Invalid image");
    exit(1);
  }

  //-------------------------Checking the image--------------------------
  if (infoHeader->bSize != 40) {
    fclose(file);
    fprintf(stderr, "Couldn't load image correctly");
    exit(1);
  }

  if ((infoHeader->planes != 1) || (infoHeader->bitCount != 24)) {
    fclose(file);
    fprintf(stderr, "Invalid image");
    exit(1);
  }

  if (infoHeader->compression != 0) {
    fclose(file);
    fprintf(stderr, "This software currently does not support compressed BMP files.\n");
    exit(1);
  }

  //Move the file through the offset until the beginning of the data itself
  fseek(file, sizeof(char) * infoHeader->fileHeader.offset, SEEK_SET);

  //Allocate the char array to the needed size to hold the data
  data = (char *) malloc (sizeof(char) * infoHeader->imageSize);

  //Actually read the image data
  fread(data, sizeof(char), infoHeader->imageSize, file);
  printf("%s", data);

  //Verify the data
  if (!data) {
    fclose(file);
    fprintf(stderr, "Couldn't load image data correctly\n");
    exit(1);
  }

  fclose(file);
  return infoHeader;

}

void writeBMP(BMP_Info_Header *header, char *data){

  FILE *fp;
  fp = fopen("output.bmp", "wb");
  int n;

  if (!fp) {
    fclose(fp);
    fprintf(stderr, "Unable to create output file\n");
    exit(1);
  }

  //-----------------------WRITE THE IMAGE------------------------
  //Header
  n = fwrite(header, sizeof(char), sizeof(BMP_Info_Header), fp);
  if (n < 1) {
    fclose(fp);
    fprintf(stderr, "Couldn't write the image header.\n");
    exit(1);
  }

  //Offset
  fseek(fp, sizeof(char) * header->fileHeader.offset, SEEK_SET);

  //Data
  n = fwrite(data, sizeof(char), header->imageSize, fp);
  if (n < 1) {
    fclose(fp);
    fprintf(stderr, "Couldn't write the image data.\n");
    exit(1);
  }

  fclose(fp);
  fprintf(stdout, "Image written successfully!\n");
}
#包括“bmp.h”
BMP_Info_Header*loadBMP(常量字符*文件名,字符*数据){
文件*文件;
BMP_Info_Header*infoHeader;
int n;
//打开文件
file=fopen(文件名,“rb”);
如果(!文件){
fprintf(stderr,“读取文件%s失败。\n”,文件名);
出口(1);
}
//Alloc并读取标题
infoHeader=(BMP_Info_Header*)malloc(sizeof(BMP_Info_Header));
n=fread(infoHeader,sizeof(BMP\u Info\u Header),1,文件);
//检查格式
if(infoHeader->fileHeader.type!=0x4D42){
fclose(文件);
fprintf(标准格式,“无效图像”);
出口(1);
}
//-------------------------检查图像--------------------------
如果(infoHeader->bSize!=40){
fclose(文件);
fprintf(stderr,“无法正确加载图像”);
出口(1);
}
如果((信息头->平面!=1)| |(信息头->比特数!=24)){
fclose(文件);
fprintf(标准格式,“无效图像”);
出口(1);
}
如果(信息头->压缩!=0){
fclose(文件);
fprintf(stderr,“此软件当前不支持压缩的BMP文件。\n”);
出口(1);
}
//通过偏移量移动文件,直到数据本身开始
fseek(文件,sizeof(char)*infoHeader->fileHeader.offset,SEEK\u SET);
//将字符数组分配到所需的大小以保存数据
数据=(char*)malloc(sizeof(char)*infoHeader->imageSize);
//实际读取图像数据
fread(数据,大小(字符),信息头->图像大小,文件);
printf(“%s”,数据);
//验证数据
如果(!数据){
fclose(文件);
fprintf(stderr,“无法正确加载图像数据\n”);
出口(1);
}
fclose(文件);
返回信息头;
}
void writeBMP(BMP\u Info\u头*头,字符*数据){
文件*fp;
fp=fopen(“output.bmp”、“wb”);
int n;
如果(!fp){
fclose(fp);
fprintf(stderr,“无法创建输出文件”\n);
出口(1);
}
//-----------------------写下图像------------------------
//标题
n=fwrite(头,sizeof(char),sizeof(BMP\u Info\u头),fp);
if(n<1){
fclose(fp);
fprintf(stderr,“无法写入图像头。\n”);
出口(1);
}
//抵消
fseek(fp,sizeof(char)*header->fileHeader.offset,SEEK\u SET);
//资料
n=fwrite(数据,大小(字符),标题->图像大小,fp);
if(n<1){
fclose(fp);
fprintf(stderr,“无法写入图像数据。\n”);
出口(1);
}
fclose(fp);
fprintf(标准输出,“图像写入成功!\n”);
}

它似乎总是在“无法写入图像数据”错误时下降。有人能帮我吗?我对编程相当陌生,无法自己解决它。

问题可能在于
fseek
,您没有检查返回值

  fwrite(header, sizeof(char), sizeof(BMP_Info_Header), fp);
  fseek(fp, sizeof(char) * header->fileHeader.offset, SEEK_SET);
  fwrite(data, sizeof(char), header->imageSize, fp);

请参阅,如果写入标题后的当前位置小于
fileHeader.offset,
,您预计会发生什么情况?用随机值填充剩余的字节?零?在任何情况下,您都应该显式地写入这些字节。

因此,我确实找到了解决问题的方法。问题是,当BMP文件未压缩时,在
BMP\u Info\u Header
结构中找到的
imageSize
变量中的值等于0,因此当我调用
fread
fwrite
函数时,它们不会读取或写入任何内容,因为
Header->imageSize
值为0。我找到的解决方案是用
header->imageSize
调用
3*header->width*header->height
,这样我就可以得到真正的图像分辨率,然后将其乘以3,这样我就可以得到准确的像素值。顺便说一下,谢谢你们的帮助!谢谢你

使用调试器并找出原因。应使用windows中定义的位图标题。h@MichaëlRoy使用的标题(
unistd.h
)表明该代码是用于*nix的。@EugeneSh。是的,我在一台MacYou电脑上,你输出的字符串(以null结尾)不是以null结尾的字符串。对printf的调用只显示第一个null之前的随机垃圾。