使用标准IO对图片数据操作

本文详细介绍了C语言中用于文件操作的标准函数fopen、fclose、fseek、fread和fwrite,以及如何使用它们来读取和修改图片文件的像素信息。通过定义图片信息和像素颜色的结构体,实现了获取图片头部信息和改变指定区域颜色的功能。此外,提供了一个完整的程序示例,演示了如何在C语言中实现这些操作。
摘要由CSDN通过智能技术生成

目录

fopen/fclose打开关闭文件函数

fseek光标操作函数

fread/fwrite函数

定义图片信息的结构体变量

定义某像素点颜色的结构体

获取图片信息函数

通过双循环改变图片某一区间的颜色

程序完整代码

fopen/fclose打开关闭文件函数

FILE *fopen(const char *pathname, const char *mode);
功能:使用标准IO接口打开文件
参数:
 pathname:文件的路径和名字
 mode:打开文件的方式
        r 以只读的方式打开文件,将光标定位到文件的开头
        r+ 以读写的方式打开文件,将光标定位到文件的开头
        w 以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,
          将光标定位到文件的开头
        w+ 以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,
          将光标定位到文件的开头
       a 以追加的方式打开文件,如果文件不存在就创建文件,如果文件存在就结尾写,将光标
          定位到文件的结尾。
       a+ 以读和追加的方式打开文件,如果文件不存在就创建文件,如果文件存在不会清空。
             如果读是从开头读,如写从结尾写
返回值:成功返回FILE指针,失败返回NULL,置位错误码


int fclose(FILE *stream);
功能:关闭文件
参数:
          stream:文件指针
返回值:成功返回0,失败返回EOF置位错误码
 

fseek光标操作函数

int fseek(FILE *stream, long offset, int whence);
功能:用来设置光标的位置
参数:
    stream:文件指针
    offset:设置到哪里(偏移)
        大于0的值         向后偏移
        等于0的值         不偏移
        小于0的值         向前偏移
    whence:从哪里开始设置
        SEEK_SET:开头
        SEEK_CUR:当前位置
        SEEK_END :结尾
返回值:成功返回0,失败返回-1置位错误码
   

fread/fwrite函数

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件中读取数据到ptr中
参数:
    ptr:用来存储读取到的数据的地址
    size:每一项的大小
    nmemb:项目的个数
    stream:文件指针
返回值:成功返回读取到的项目的个数,
        如果size是1,返回的项目的个数就是字节的个数
  失败返回小于项目的个数或者是0
        如果是失败需要通过ferror或者feof判断是那种错误

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:将ptr中的数据写入到文件中
参数:
    ptr:写数据的首地址
    size:每一项的大小
    nmemb:项目的个数
    stream:文件指针
返回值:成功返回写入项目的个数,
失败或者到文件结尾了返回小于项目的个数或者是0

定义图片信息的结构体变量

typedef struct picture {
    unsigned int size; //图像大小,单位字节
    unsigned int offset; //图像头大小,单位字节
    unsigned int width; //图像宽度,单位像素
    unsigned int high; //图像高度,单位像素
    unsigned short pix;//
} p_t;

定义某像素点颜色的结构体

typedef struct {
    unsigned char B; //蓝
    unsigned char G; //绿
    unsigned char R; //红
} RGB_t;

获取图片信息函数

void get_picture_head_info(FILE* fp, p_t* info)
{
    fseek(fp, 2, SEEK_SET);
    fread(&info->size, 4, 1, fp);

    fseek(fp, 10, SEEK_SET);
    fread(&info->offset, 4, 1, fp);

    fseek(fp, 18, SEEK_SET);
    fread(&info->width, 4, 1, fp);
    fread(&info->high, 4, 1, fp);

    fseek(fp, 2, SEEK_CUR);
    fread(&info->pix, 2, 1, fp);
}

通过双循环改变图片某一区间的颜色

 memset(&rgb, 0, sizeof(rgb));
    rgb.G = 0; // 黑色
    rgb.R = 0;
    rgb.B = 0;
    int wide = 30;
    int heigh = 30;
    fseek(fp, 54 + 899538, SEEK_SET);
    for (int j = 0; j < heigh; j++) {
        for (int i = 0; i < wide; i++) {
            fwrite(&rgb, 3, 1, fp);
        }
        fseek(fp, (info.width - wide) * 3, SEEK_CUR);
    }

程序完整代码

//使用标准IO对图片数据操作
#include <head.h>
typedef struct picture {
    unsigned int size; //图像大小,单位字节
    unsigned int offset; //图像头大小,单位字节
    unsigned int width; //图像宽度,单位像素
    unsigned int high; //图像高度,单位像素
    unsigned short pix; //
} p_t;

typedef struct {
    unsigned char B; //蓝
    unsigned char G; //绿
    unsigned char R; //红
} RGB_t;

void get_picture_head_info(FILE* fp, p_t* info)
{
    fseek(fp, 2, SEEK_SET);
    fread(&info->size, 4, 1, fp);

    fseek(fp, 10, SEEK_SET);
    fread(&info->offset, 4, 1, fp);

    fseek(fp, 18, SEEK_SET);
    fread(&info->width, 4, 1, fp);
    fread(&info->high, 4, 1, fp);

    fseek(fp, 2, SEEK_CUR);
    fread(&info->pix, 2, 1, fp);
}

int main(int argc, const char* argv[])
{
    FILE* fp;
    p_t info;
    RGB_t rgb;
    if (argc != 2) {
        fprintf(stderr, "input error,try again\n");
        fprintf(stderr, "usage:./a.out picturename\n");
        return -1;
    }

    if ((fp = fopen(argv[1], "r+")) == NULL)
        PRINT_ERR("fopen error");

    get_picture_head_info(fp, &info);

    fseek(fp, 54, SEEK_SET);
    fread(&rgb, 3, 1, fp);

    memset(&rgb, 0, sizeof(rgb));
    rgb.G = 0; // 黑色
    rgb.R = 0;
    rgb.B = 0;
    int wide = 30;
    int heigh = 30;
    fseek(fp, 54 + 899538, SEEK_SET);
    for (int j = 0; j < heigh; j++) {
        for (int i = 0; i < wide; i++) {
            fwrite(&rgb, 3, 1, fp);
        }
        fseek(fp, (info.width - wide) * 3, SEEK_CUR);
    }

    fclose(fp);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值