Bmp文件格式分析,含Bmp文件处理函数库()

​​​​​​一、BMP文件头信息:共54个字节

  • 第一部分(前14个字节):为文件信息,结构体信息如下所示
/**
 * bmp文件信息
*/
#pragma pack(1)
typedef struct
{
    char            type[2];      //文件类型
    unsigned int    size;         //文件大小
    unsigned short  reserved1;    //保留, 必须为零
    unsigned short  reserved2;    //保留, 必须为零
    unsigned int    offset;       //从头到位图数据的偏移
}FileInof_t;
#pragma pack()
  • 第二部分(后40个字节):为位图信息,结构体信息如下所示
/**
 * 位图信息
*/
#pragma pack(1)
typedef struct
{
    unsigned int size;          //本结构体所占用字节数, 即40个字节	
    int width;                  //位图的宽度, 以像素为单位, 像素数量是4字节对齐的	
    int height;                 // 位图的高度, 以像素为单位	
    unsigned short planes;      // 目标设备的级别, 必须为1	
    unsigned short count;       // 每个像素所需的位数, 必须是1(双色, 4(16色), 8(256色)或24(真彩色) 之一	
    unsigned int compression;   // 位图压缩类型, 必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型) 之一	
    unsigned int sizeimage;     // 位图的大小, 以字节为单位	
    unsigned int xmeter;        // 位图水平分辨率, 每米像素数	
    unsigned int ymeter;        // 位图垂直分辨率, 每米像素数	
    unsigned int cused;         // 位图实际使用的颜色表中的颜色数	
    unsigned int cimportant;    // 位图显示过程中重要的颜色数
}BitMapInfo_t;
#pragma pack()

二、BMP文件RGB位图数据

  • 在前54个字节之后的数据为RGB位图数据

三、BMP文件处理函数库

  • 头文件 BmpLib.h
#ifndef _BMPLIB_H_
#define _BMPLIB_H_

#include <stdio.h>

/**
 * bmp文件信息
*/
#pragma pack(1)
typedef struct
{
    char            type[2];      //文件类型
    unsigned int    size;         //文件大小
    unsigned short  reserved1;    //保留, 必须为零
    unsigned short  reserved2;    //保留, 必须为零
    unsigned int    offset;       //从头到位图数据的偏移
}FileInof_t;
#pragma pack()

/**
 * 位图信息
*/
#pragma pack(1)
typedef struct
{
    unsigned int size;          //本结构体所占用字节数, 即40个字节	
    int width;                  //位图的宽度, 以像素为单位, 像素数量是4字节对齐的	
    int height;                 // 位图的高度, 以像素为单位	
    unsigned short planes;      // 目标设备的级别, 必须为1	
    unsigned short count;       // 每个像素所需的位数, 必须是1(双色, 4(16色), 8(256色)或24(真彩色) 之一	
    unsigned int compression;   // 位图压缩类型, 必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型) 之一	
    unsigned int sizeimage;     // 位图的大小, 以字节为单位	
    unsigned int xmeter;        // 位图水平分辨率, 每米像素数	
    unsigned int ymeter;        // 位图垂直分辨率, 每米像素数	
    unsigned int cused;         // 位图实际使用的颜色表中的颜色数	
    unsigned int cimportant;    // 位图显示过程中重要的颜色数
}BitMapInfo_t;
#pragma pack()

/**
 * bmp文件头
*/
typedef struct
{
    FileInof_t      fileinfo;
    BitMapInfo_t    bitmap;
}BmpHeader_t;

/**
 * bmp文件
*/
typedef struct 
{
    BmpHeader_t header;
    int pixwszie;           //bmp图片宽(单位:像素)
    int pixhsize;           //bmp图片高(单位:像素)
    int pixsize;            //bmp图片分辨率(单位:像素)
    int imgsize;            //bmp图片占内存大小(不包含文件头)(单位:字节)
    char pathname[64];      //文件名
    unsigned char *imgsrc;
}Bmp_t;

/**
 * 操作模式
*/
typedef enum
{
    BMPMDLI_TO_GRAY = 0,
    BMPMDLI_TO_BINARY = 1,
}BmpMdliMode_t;

/**
 * 灰度计算方式
*/
typedef enum
{
    CALCU_METHOD_TYPICAL = 0,
    CALCU_METHOD_PHOTOSHOW = 1,
    CALCU_METHOD_AVERAGE = 2,
}CalculationMethod_t;

/**
 * BMP位图数据输出格式
*/
typedef enum
{
    BMP_BITMAP_FORMAT_RGB_FRONT = 0,    /* RGB数据, 顺序排列 */
    BMP_BITMAP_FORMAT_RGB_BACK = 1,     /* RGB数据, 反序排列 */
    BMP_BITMAP_FORMAT_BGR_FRONT = 2,    /* BGR数据, 顺序排列 */
    BMP_BITMAP_FORMAT_BGR_BACK = 3,     /* BGR数据, 反序排列 */
}BmpBitMapFormat_t;

/*********************************************
 * 功能:打开bmp文件
 * 参数:
 *      path:文件路径+文件名
 * 返回值:
 *      NULL:打开失败
 *      Bmp_t *:文件句柄
**********************************************/
extern Bmp_t *BmpFileOpen(char *path);    //打开bmp文件

/*********************************************
 * 功能:释放bmp文件
 * 参数:
 *      bmp:bmp文件句柄
**********************************************/
extern int BmpFileClose(Bmp_t *bmp);      //关闭bmp文件

/*********************************************
 * 功能:创建bmp文件
 * 参数:
 *      imgsrc:RGB数据
 *      width:bmp宽
 *      height:bmp高
 *      bitdepth:位深度(8, 16, 24, 32)
 * 返回值:
 *      NULL:创建失败
 *      Bmp_t *:bmp句柄
**********************************************/
extern Bmp_t *BmpFileCreat(unsigned char *imgsrc, int width, int height, int bitdepth);

/*********************************************
 * 功能:保存bmp文件
 * 参数:
 *      path:保存路径 + 文件名
 *      bmp:bmp句柄
 * 返回值:
 *       -1:保存失败
 *      > 0:保存成功
**********************************************/
extern int BmpFileSave(char *path, Bmp_t *bmp);

/*********************************************
 * 功能:保存Bitmap数据
 * 参数:
 *      path:保存路径 + 文件名
 *      bmp:bmp句柄
 * 返回值:
 *       -1:保存失败
 *      > 0:保存成功
**********************************************/
int BmpFileSaveBitMap(char *path, Bmp_t *bmp, BmpBitMapFormat_t bmapformat);

/*********************************************
 * 功能:输出bmp文件信息
 * 参数:
 *      bmp:bmp句柄
**********************************************/
extern void BmpFileInfoShow(Bmp_t *bmp);

/*********************************************
 * 功能:RGB转灰度图
 * 参数:
 *      calmeth:转换方法
 *      rgb:bmp句柄
 * 返回值:
 *      NULL:转换失败
 *      Bmp_t *:灰度图bmp句柄
**********************************************/
extern Bmp_t *BmpRgbToGray(CalculationMethod_t calmeth, Bmp_t *rgb);   //bmp转gray

/*********************************************
 * 功能:bmp灰度图二值化
 * 参数:
 *      threshold:转换阈值(0 ~ 255)
 *      rgb:bmp句柄
 * 返回值:
 *      NULL:转换失败
 *      Bmp_t *:二值图bmp句柄
**********************************************/
extern Bmp_t *BmpGrayToBinary(unsigned char  threshold, Bmp_t *gray);


#endif
  • 头文件 RGB2Gray.h
#ifndef _RGB2GRAY_H_
#define _RGB2GRAY_H_

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用通用算法计算
*/
extern void RGB2GrayTypical(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix);

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用PhotoShop原理计算
*/
extern void RGB2GrayInPhotoShop(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix);

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用均值计算
*/
extern void RGB2GrayAverage(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix);

#endif
  • 源文件 BmpLib.c  RGB2Gray.c

       源码在下面,也可以下载,连接:https://download.csdn.net/download/MoDa_Li/12667948

       使用 gcc 编译需要添加 math库 -lm,g++不需要

/*********************************************
 * file:BmpLib.c
 * brief introduction:dealwith bmp file
 * authon:li
 * creat by 2019/6
**********************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "BmpLib.h"
#include "RGB2Gray.h"

/*********************************************
 * 功能:打开bmp文件
 * 参数:
 *      path:文件路径+文件名
 * 返回值:
 *      NULL:打开失败
 *      Bmp_t *:文件句柄
**********************************************/
Bmp_t *BmpFileOpen(char *path)
{
    FILE *fp = fopen(path, "r");
    if(fp == NULL)
    {
        printf("open %s failed...\r\n", path);
        return NULL;
    }

    Bmp_t *bmp = (Bmp_t *)malloc(sizeof(Bmp_t));
    if(bmp == NULL)
    {
        printf("bmp malloc error...\r\n");
        fclose(fp);
        return NULL;
    }
    memset(bmp, 0x00, sizeof(Bmp_t));

    strcpy(bmp->pathname, path);

    int ret = 0;

    ret = fread(bmp, sizeof(BmpHeader_t), 1, fp);
    if(ret < 0)
    {
        printf("fread Bmp_t error...\r\n");
        free(bmp);
        fclose(fp);
        return NULL;
    }

    if(bmp->header.fileinfo.type[0] != 'B' || bmp->header.fileinfo.type[1] != 'M')
    {
        printf("%s is not bmp file, can not open...\r\n", path);
        free(bmp);
        fclose(fp);
        return NULL;
    }

    bmp->pixwszie = bmp->header.bitmap.width;
    bmp->pixhsize = bmp->header.bitmap.height;
    bmp->pixsize = bmp->header.bitmap.width * bmp->header.bitmap.height;
    bmp->imgsize = bmp->header.bitmap.sizeimage;

    bmp->imgsrc = (unsigned char *)malloc(bmp->imgsize);
    if(bmp->imgsrc == NULL)
    {
        printf("malloc bmp->imgsrc error...\r\n");
        free(bmp);
        fclose(fp);
        return NULL;
    }


    ret = fread(bmp->imgsrc, bmp->imgsize, 1, fp);
    if(ret < 0)
    {
        printf("fread imgsrc error...\r\n");
        free(bmp);
        free(bmp->imgsrc);
        fclose(fp);
        return NULL;
    }

    fclose(fp);
    return bmp;
}

/*********************************************
 * 功能:释放bmp文件
 * 参数:
 *      bmp:bmp文件句柄
**********************************************/
int BmpFileClose(Bmp_t *bmp)
{
    if(bmp == NULL)
        return -1;
    
    if(bmp->imgsrc != NULL)
        free(bmp->imgsrc);

    free(bmp);
    return 0;
}

/*********************************************
 * 功能:创建bmp文件
 * 参数:
 *      imgsrc:RGB数据
 *      width:bmp宽
 *      height:bmp高
 *      bitdepth:位深度(8, 16, 24, 32)
 * 返回值:
 *      NULL:创建失败
 *      Bmp_t *:bmp句柄
**********************************************/
Bmp_t *BmpFileCreat(unsigned char *imgsrc, int width, int height, int bitdepth)
{
    Bmp_t *bmp = (Bmp_t *)malloc(sizeof(Bmp_t));
    if(bmp == NULL)
    {
        printf("bmp malloc error...\r\n");
        return NULL;
    }
    memset(bmp, 0x00, sizeof(Bmp_t));

/*************** Bmp_t start ***************/
    /* FileInof_t start */
    bmp->header.fileinfo.type[0] = 'B';
    bmp->header.fileinfo.type[1] = 'M';
    bmp->header.fileinfo.size = (width*height*bitdepth/8) + 54;
    bmp->header.fileinfo.reserved1 = 0;
    bmp->header.fileinfo.reserved2 = 0;
    bmp->header.fileinfo.offset = 54;
    /* FileInof_t end */

    /* BitMapInfo_t start */
    bmp->header.bitmap.size = 40;
    bmp->header.bitmap.width = width;
    bmp->header.bitmap.height = height;
    bmp->header.bitmap.planes = 1;
    bmp->header.bitmap.count = bitdepth;
    bmp->header.bitmap.compression = 0;
    bmp->header.bitmap.sizeimage = (width*height*bitdepth/8);
    bmp->header.bitmap.xmeter = width*3;
    bmp->header.bitmap.ymeter = height*3;
    bmp->header.bitmap.cused = 0;
    bmp->header.bitmap.cimportant = 0;
    /* BitMapInfo_t end */

    bmp->pixwszie = width;           //bmp图片宽(单位:像素)
    bmp->pixhsize = height;           //bmp图片高(单位:像素)
    bmp->pixsize = width*height;            //bmp图片分辨率(单位:像素)
    bmp->imgsize = (width*height*bitdepth/8); //bmp图片占内存大小(不包含文件头)(单位:字节)
    memset(bmp->pathname, 0, 64);
    bmp->imgsrc = (unsigned char *)malloc(width*height*bitdepth/8);
    if(bmp->imgsrc == NULL)
    {
        printf("bmp->imgsrc malloc error...\r\n");
        free(bmp);
        return NULL;
    }
    memcpy(bmp->imgsrc, imgsrc, width*height*bitdepth/8);
/*************** Bmp_t end ***************/
    return bmp;
}

/*********************************************
 * 功能:保存bmp文件
 * 参数:
 *      path:保存路径 + 文件名
 *      bmp:bmp句柄
 * 返回值:
 *       -1:保存失败
 *      > 0:保存成功
**********************************************/
int BmpFileSave(char *path, Bmp_t *bmp)
{
    FILE *fp = fopen(path, "w");
    if(fp == NULL)
    {
        printf("open %s failed...\r\n", path);
        return -1;
    }

    int ret = 0;

    ret = fwrite(&bmp->header, sizeof(BmpHeader_t), 1, fp);
    if(ret < 0)
    {
        printf("fwrite bmp->header error...\r\n");
        fclose(fp);
        return -1;
    }
    ret = fwrite(bmp->imgsrc, bmp->imgsize, 1, fp);
    if(ret < 0)
    {
        printf("fwrite bmp->imgsrc error...\r\n");
        fclose(fp);
        return -1;
    }
    fflush(fp);

    return fclose(fp);
}

/*********************************************
 * 功能:保存Bitmap数据
 * 参数:
 *      path:保存路径 + 文件名
 *      bmp:bmp句柄
 *      bmapformat:bitmap保存方式
 * 返回值:
 *       -1:保存失败
 *      > 0:保存成功
**********************************************/
int BmpFileSaveBitMap(char *path, Bmp_t *bmp, BmpBitMapFormat_t bmapformat)
{
    int ret = 0;

    FILE *fp = fopen(path, "w");
    if(fp == NULL)
    {
        printf("open %s failed...\r\n", path);
        return -1;
    }

    switch (bmapformat)
    {
    case BMP_BITMAP_FORMAT_RGB_FRONT:
    {
        unsigned char *tmpbuf = (unsigned char *)malloc(bmp->imgsize);
        if(tmpbuf == NULL)
        {
            printf("BmpFileSaveBitMap: malloc error, malloc size: %d\r\n", bmp->imgsize);
            fclose(fp);
            return -1;
        }
        for(int i = 0, j = bmp->imgsize - 1; i < bmp->imgsize; i++, j--)
            tmpbuf[i] = bmp->imgsrc[j];
        ret = fwrite(tmpbuf, bmp->imgsize, 1, fp);
        if(ret < 0)
        {
            printf("fwrite bmp->imgsrc error...\r\n");
            fclose(fp);
            free(tmpbuf);
            return -1;
        }
        free(tmpbuf);
        break;
    }
    case BMP_BITMAP_FORMAT_RGB_BACK:
    {
        unsigned char *tmpbuf = (unsigned char *)malloc(bmp->imgsize);
        if(tmpbuf == NULL)
        {
            printf("BmpFileSaveBitMap: malloc error, malloc size: %d\r\n", bmp->imgsize);
            fclose(fp);
            return -1;
        }

        for(int i = 0; i < bmp->imgsize; i += 3)
        {
            tmpbuf[i    ] = bmp->imgsrc[i + 2];
            tmpbuf[i + 1] = bmp->imgsrc[i + 1];
            tmpbuf[i + 2] = bmp->imgsrc[i    ];
        }

        ret = fwrite(tmpbuf, bmp->imgsize, 1, fp);
        if(ret < 0)
        {
            printf("fwrite bmp->imgsrc error...\r\n");
            fclose(fp);
            free(tmpbuf);
            return -1;
        }
        free(tmpbuf);
        break;
    }
    case BMP_BITMAP_FORMAT_BGR_FRONT:
    {
        unsigned char *tmpbuf = (unsigned char *)malloc(bmp->imgsize);
        if(tmpbuf == NULL)
        {
            printf("BmpFileSaveBitMap: malloc error, malloc size: %d\r\n", bmp->imgsize);
            fclose(fp);
            return -1;
        }

        for(int i = 0, j = bmp->imgsize - 1; i < bmp->imgsize; i += 3, j-= 3)
        {
            tmpbuf[i    ] = bmp->imgsrc[j - 2];
            tmpbuf[i + 1] = bmp->imgsrc[j - 1];
            tmpbuf[i + 2] = bmp->imgsrc[j    ];
        }

        ret = fwrite(tmpbuf, bmp->imgsize, 1, fp);
        if(ret < 0)
        {
            printf("fwrite bmp->imgsrc error...\r\n");
            fclose(fp);
            free(tmpbuf);
            return -1;
        }
        free(tmpbuf);
        break;
    }
    case BMP_BITMAP_FORMAT_BGR_BACK:
    {
        ret = fwrite(bmp->imgsrc, bmp->imgsize, 1, fp);
        if(ret < 0)
        {
            printf("fwrite bmp->imgsrc error...\r\n");
            fclose(fp);
            return -1;
        }
        break;
    }
        
    default:
        break;
    }

    
    fflush(fp);
    return fclose(fp);
}

int BmpFileNV21ToBitMap()
{

}

/**
 *   NV12: YYYYYYYY UVUV
 * 
 *   NV21: YYYYYYYY VUVU
 *   ( 8 * 2)   
 *   |Y0 Y1|Y2   Y3 |Y4  Y5 |Y6  Y7 |
 *   |Y8 Y9|Y10  Y11|Y12 Y13|Y14 Y15|
 *   |V0 U0|V1   U1 |V2   U2|V3   U3|
 * 
*/
int BmpFileNV21HnadleWith(unsigned char *nv21src, unsigned char *nv21det, int nvwidth, int nvheight, int ctrl)
{
    unsigned char *ydata = nv21src;
    int ylength = nvwidth * nvheight;

    unsigned short *vudata = (unsigned short *)(nv21src + ylength);
}

/*********************************************
 * 功能:输出bmp文件信息
 * 参数:
 *      bmp:bmp句柄
**********************************************/
void BmpFileInfoShow(Bmp_t *bmp)
{
    printf("\r\n----- BmpFileInfoShow ----->\r\n");
    printf("    file path: %s\r\n", bmp->pathname);

    printf("(1) ---> FileInof_t\r\n");
    printf("    bmp->header.fileinfo.type: %c%c\r\n", bmp->header.fileinfo.type[0], bmp->header.fileinfo.type[1]);
    printf("    bmp->header.fileinfo.size: %d\r\n", bmp->header.fileinfo.size);
    printf("    bmp->header.fileinfo.reserved1: %d\r\n", bmp->header.fileinfo.reserved1);
    printf("    bmp->header.fileinfo.reserved2: %d\r\n", bmp->header.fileinfo.reserved2);
    printf("    bmp->header.fileinfo.offset: %d\r\n", bmp->header.fileinfo.offset);

    printf("(2) ---> BitMapInfo_t\r\n");
    printf("    bmp->header.bitmap.size: %d\r\n", bmp->header.bitmap.size);
    printf("    bmp->header.bitmap.width: %d\r\n", bmp->header.bitmap.width);
    printf("    bmp->header.bitmap.height: %d\r\n", bmp->header.bitmap.height);
    printf("    bmp->header.bitmap.planes: %d\r\n", bmp->header.bitmap.planes);
    printf("    bmp->header.bitmap.count: %d\r\n", bmp->header.bitmap.count);
    printf("    bmp->header.bitmap.compression: %d\r\n", bmp->header.bitmap.compression);
    printf("    bmp->header.bitmap.sizeimage: %d\r\n", bmp->header.bitmap.sizeimage);
    printf("    bmp->header.bitmap.xmeter: %d\r\n", bmp->header.bitmap.xmeter);
    printf("    bmp->header.bitmap.ymeter: %d\r\n", bmp->header.bitmap.ymeter);
    printf("    bmp->header.bitmap.cused: %d\r\n", bmp->header.bitmap.cused);
    printf("    bmp->header.bitmap.cimportant: %d\r\n", bmp->header.bitmap.cimportant);

    printf("(3) ---> Bmp_t\r\n");
    printf("    bmp->header { BmpHeader_t }\r\n");
    printf("    bmp->pixwszie: %d\r\n", bmp->pixwszie);
    printf("    bmp->pixhsize: %d\r\n", bmp->pixhsize);
    printf("    bmp->pixsize: %d\r\n", bmp->pixsize);
    printf("    bmp->imgsize: %d\r\n", bmp->imgsize);
    printf("----- BmpFileInfoShow end -----\r\n\r\n");
}

/*********************************************
 * 功能:RGB转灰度图
 * 参数:
 *      calmeth:转换方法
 *      rgb:bmp句柄
 * 返回值:
 *      NULL:转换失败
 *      Bmp_t *:灰度图bmp句柄
**********************************************/
Bmp_t *BmpRgbToGray(CalculationMethod_t calmeth, Bmp_t *rgb)
{
    if(rgb == NULL)
    {
        printf("rgb is null...\r\n");
        return NULL;
    }

    if(rgb->imgsrc == NULL)
    {
        printf("rgb->imgsrc is null...\r\n");
        return NULL;
    }

    Bmp_t *gray = (Bmp_t *)malloc(sizeof(Bmp_t));
    if(gray == NULL)
    {
        printf("gray malloc error...\r\n");
        return NULL;
    }
    memset(gray, 0x00, sizeof(Bmp_t));

    memcpy(gray, rgb, sizeof(Bmp_t));
    gray->imgsrc = NULL;

    gray->imgsrc = (unsigned char *)malloc(rgb->imgsize);
    if(gray->imgsrc == NULL)
    {
        printf("malloc gray->imgsrc error...\r\n");
        free(gray);
        return NULL;
    }

    switch (calmeth)
    {
    case CALCU_METHOD_TYPICAL:
        RGB2GrayTypical(gray->imgsrc, gray->pixsize, rgb->imgsrc, rgb->pixsize);
        break;
    case CALCU_METHOD_PHOTOSHOW:
        RGB2GrayInPhotoShop(gray->imgsrc, gray->pixsize, rgb->imgsrc, rgb->pixsize);
        break;
    case CALCU_METHOD_AVERAGE:
        RGB2GrayAverage(gray->imgsrc, gray->pixsize, rgb->imgsrc, rgb->pixsize);
        break;
    
    default:
        printf("CalculationMethod_t error...\r\n");
        free(gray);
        free(gray->imgsrc);
        return NULL;
    }    

    return gray;
}

/*********************************************
 * 功能:bmp灰度图二值化
 * 参数:
 *      threshold:转换阈值(0 ~ 255)
 *      rgb:bmp句柄
 * 返回值:
 *      NULL:转换失败
 *      Bmp_t *:二值图bmp句柄
**********************************************/
Bmp_t *BmpGrayToBinary(unsigned char threshold, Bmp_t *gray)
{
    if(gray == NULL)
    {
        printf("gray is null...\r\n");
        return NULL;
    }

    if(gray->imgsrc == NULL)
    {
        printf("gray->imgsrc is null...\r\n");
        return NULL;
    }

    Bmp_t *binary = (Bmp_t *)malloc(sizeof(Bmp_t));
    if(binary == NULL)
    {
        printf("binary malloc error...\r\n");
        return NULL;
    }
    memset(binary, 0x00, sizeof(Bmp_t));

    memcpy(binary, gray, sizeof(Bmp_t));
    binary->imgsrc = NULL;

    binary->imgsrc = (unsigned char *)malloc(gray->imgsize);
    if(binary->imgsrc == NULL)
    {
        printf("malloc binary->imgsrc error...\r\n");
        free(binary);
        return NULL;
    }

    for (int i = 0; i < gray->pixsize; i++)
    {		
        if(gray->imgsrc[3 * i] > threshold)	
            binary->imgsrc[3 * i + 0] = binary->imgsrc[3 * i + 1] = binary->imgsrc[3 * i + 2] = 255;
        else
            binary->imgsrc[3 * i + 0] = binary->imgsrc[3 * i + 1] = binary->imgsrc[3 * i + 2] = 0;
    }

    return binary;
}
/**
 *filename:RGB2Gray.c
 */

#include <stdio.h>
#include <math.h>

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用通用算法计算
*/
void RGB2GrayTypical(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix)
{
    if(GrayImg == NULL || GrayImgSizePix < SrcImgSizePix || SrcImage == NULL || SrcImgSizePix <= 0)
        return;

    int GrayValue = 0;
    for (int i = 0; i < SrcImgSizePix; i++)
    {		
        unsigned char b = (unsigned char)SrcImage[3 * i + 0];		
        unsigned char g = (unsigned char)SrcImage[3 * i + 1];		
        unsigned char r = (unsigned char)SrcImage[3 * i + 2];		
        GrayValue = r * 0.299 + g * 0.587 + b * 0.114;	
        GrayImg[3 * i + 0] = GrayImg[3 * i + 1] = GrayImg[3 * i + 2] = GrayValue;
    }
}

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用PhotoShop原理计算
*/
void RGB2GrayInPhotoShop(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix)
{	
    if(GrayImg == NULL || GrayImgSizePix < SrcImgSizePix || SrcImage == NULL || SrcImgSizePix <= 0)
        return;

    for (int i = 0; i < SrcImgSizePix; i++)	
    {		
        unsigned char b = SrcImage[3 * i + 0];		
        unsigned char g = SrcImage[3 * i + 1];		
        unsigned char r = SrcImage[3 * i + 2];		
        GrayImg[3 * i + 0] = GrayImg[3 * i + 1] = GrayImg[3 * i + 2] = pow((pow(r, 2.2) * 0.2973 + pow(g, 2.2) * 0.6274 + pow(b, 2.2) * 0.0753), 1/2.2);	
    }
}

/**
 * 功能:RGB图像转灰度图
 * 参数:
 *      GrayImg:灰度图数据缓存区
 *      GrayImgSizePix:灰度图数据缓存区大小(单位:像素)
 *      SrcImage:RGB图源数据
 *      SrcImgSizePix:RGB图源数据大小(单位:像素)
 * 原理:使用均值计算
*/
void RGB2GrayAverage(unsigned char *GrayImg, int GrayImgSizePix, unsigned char *SrcImage, int SrcImgSizePix)
{	
    if(GrayImg == NULL || GrayImgSizePix < SrcImgSizePix || SrcImage == NULL || SrcImgSizePix <= 0)
        return;

    for (int i = 0; i < SrcImgSizePix; i++)	
    {		
        unsigned char b = SrcImage[3 * i + 0];		
        unsigned char g = SrcImage[3 * i + 1];		
        unsigned char r = SrcImage[3 * i + 2];		
        GrayImg[3 * i + 0] = GrayImg[3 * i + 1] = GrayImg[3 * i + 2] = (b + g + r) / 3;	
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值