文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>图像基本处理--C语言实现

图像基本处理--C语言实现

时间:2010-08-15  来源:sep

2010/8/15   DONE:BMP图像的翻转和镜像 TODO:BMP图像灰度化   2010/8/16   DONE:BMP图像灰度化 TODO:JPG解码   效果如下: source image:   mirror image:   rotate image:   gray image:


/**
// img_convert.c
//
// A small sample program that creates mirror image and rotate image,
// source image must be bmp format
//
// comiple as:
// gcc img_convert.c
//
// Run using:
// ./a.out
//
**/

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

#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned long

#pragma pack(2)
typedef struct BMP_Head_t {
    uint16_t identifier;
    uint32_t file_size;
    uint32_t reserved;
    uint32_t data_offset;
} BMP_Head_t;

typedef struct BMP_MapInfo_t {
    uint32_t header_size;
    uint32_t width;
    uint32_t height;
    uint16_t n_planes;
    uint16_t bits_per_pixel;
    uint32_t compression;
    uint32_t data_size;
    uint32_t hresolution;
    uint32_t vresolution;
    uint32_t n_colors_used;
    uint32_t n_important_colors;
} BMP_MapInfo_t;
#pragma pack()

typedef struct BMP_Container_t {
    char *file_name;
    BMP_Head_t head;
    BMP_MapInfo_t map_info;
    unsigned char *img_data_buf;
    
    int has_init;
} BMP_Container_t;


int BMP_Rotate(const char *f, BMP_Container_t *c)
{
    FILE *fp = NULL;
    int row, line_size;
    int retval = -1;
    
    if (!f || !c || !c->has_init) return -1;
        
    fp = fopen(f, "wb");
    if (!fp) {
        fprintf(stderr, "ROTATE: fopen file Error.\n");
        goto exit_err;
    }
    
    /* fill bitmap head */
    if (sizeof(BMP_Head_t) != fwrite(&c->head, 1, sizeof(BMP_Head_t), fp)) {
        fprintf(stderr, "ROTATE: fwrite bitmap.head Error.\n");
        goto exit_err;
    }

    /* fill bitmap map information */
    if (sizeof(BMP_MapInfo_t) != fwrite(&c->map_info, 1, sizeof(BMP_MapInfo_t), fp)) {
        fprintf(stderr, "ROTATE: fwrite bitmap.mapinfo Error.\n");
        goto exit_err;
    }

    /* get bytes of one line */
    line_size = c->map_info.width*c->map_info.bits_per_pixel/8;

    /* rotate & fill bitmap image data */
    for (row = c->map_info.height-1; row >= 0; row--) {
        fwrite(&c->img_data_buf[row*line_size], 1, line_size, fp);
    }
    
    retval = 0;
    
exit_err:
    if (fp) fclose(fp);
    return retval;
}

int BMP_Mirror(const char *f, BMP_Container_t *c)
{
    FILE *fp = NULL;
    unsigned char *buf = NULL;
    int row, n_pixel, n_byte;
    int line_size, bytes_per_pixel;
    int retval = -1;
    
    if (!f || !c || !c->has_init) return -1;
        
    fp = fopen(f, "wb");
    if (!fp) {
        fprintf(stderr, "MIRROR: fopen file Error.\n");
        goto exit_err;
    }
    
    /* fill bitmap head */
    if (sizeof(BMP_Head_t) != fwrite(&c->head, 1, sizeof(BMP_Head_t), fp)) {
        fprintf(stderr, "MIRROR: fwrite bitmap.head Error.\n");
        goto exit_err;
    }

    /* fill bitmap map information */
    if (sizeof(BMP_MapInfo_t) != fwrite(&c->map_info, 1, sizeof(BMP_MapInfo_t), fp)) {
        fprintf(stderr, "MIRROR: fwrite bitmap.mapinfo Error.\n");
        goto exit_err;
    }

    /* get bytes of one line */
    bytes_per_pixel = c->map_info.bits_per_pixel/8;
    line_size = c->map_info.width*bytes_per_pixel;

    /* allocate memory for one line data of image */
    buf = (unsigned char *)malloc(line_size);
    if (!buf) {
        fprintf(stderr, "MIRROR: Can't allocate memory for line buffer.\n");
        goto exit_err;
    }

    /* mirror & fill bitmap image data */
    for (row = 0; row < c->map_info.height; row++) {
        for (n_pixel = 0; n_pixel < c->map_info.width; n_pixel++) {
            for (n_byte = 0; n_byte < bytes_per_pixel; n_byte++) {
                buf[n_pixel*bytes_per_pixel+n_byte] =
                    *(unsigned char *)((&c->img_data_buf[row*line_size]) + (c->map_info.width-n_pixel-1)*bytes_per_pixel + n_byte);
            }
        }

        fwrite(buf, 1, line_size, fp);
    }
    
    retval = 0;

exit_err:
    if (buf) free(buf);
    if (fp) fclose(fp);
    return retval;
}

int BMP_Gray(const char *f, BMP_Container_t *c)
{
    FILE *fp = NULL;
    unsigned char *buf = NULL;
    int row, n_pixel;
    int line_size, bytes_per_pixel;
    int retval = -1;
    unsigned char blue, red, green, Y;
    
    if (!f || !c || !c->has_init) return -1;
        
    fp = fopen(f, "wb");
    if (!fp) {
        fprintf(stderr, "MIRROR: fopen file Error.\n");
        goto exit_err;
    }
    
    /* fill bitmap head */
    if (sizeof(BMP_Head_t) != fwrite(&c->head, 1, sizeof(BMP_Head_t), fp)) {
        fprintf(stderr, "MIRROR: fwrite bitmap.head Error.\n");
        goto exit_err;
    }

    /* fill bitmap map information */
    if (sizeof(BMP_MapInfo_t) != fwrite(&c->map_info, 1, sizeof(BMP_MapInfo_t), fp)) {
        fprintf(stderr, "MIRROR: fwrite bitmap.mapinfo Error.\n");
        goto exit_err;
    }

    /* get bytes of one line */
    bytes_per_pixel = c->map_info.bits_per_pixel/8;
    line_size = c->map_info.width*bytes_per_pixel;

    /* allocate memory for one line data of image */
    buf = (unsigned char *)malloc(line_size);
    if (!buf) {
        fprintf(stderr, "MIRROR: Can't allocate memory for line buffer.\n");
        goto exit_err;
    }

    /* gray & fill bitmap image data */
    for (row = 0; row < c->map_info.height; row++) {
        for (n_pixel = 0; n_pixel < c->map_info.width; n_pixel++) {
            /* get blue, red & green */
            blue = *(unsigned char *)((&c->img_data_buf[row*line_size]) + n_pixel*bytes_per_pixel + 0);
            green = *(unsigned char *)((&c->img_data_buf[row*line_size]) + n_pixel*bytes_per_pixel + 1);
            red = *(unsigned char *)((&c->img_data_buf[row*line_size]) + n_pixel*bytes_per_pixel + 2);
            /* Y=0.299*R+0.587*G+0.114*B */
            Y = (unsigned char)(0.299*red + 0.587*green + 0.114*blue);

            buf[n_pixel*bytes_per_pixel+0] = Y;
            buf[n_pixel*bytes_per_pixel+1] = Y;
            buf[n_pixel*bytes_per_pixel+2] = Y;
        }

        fwrite(buf, 1, line_size, fp);
    }
    
    retval = 0;

exit_err:
    if (buf) free(buf);
    if (fp) fclose(fp);
    return retval;
}

int BMP_Initiate(const char *f, BMP_Container_t *c)
{
    FILE *fp = NULL;
    int retval = -1;
    
    if (!f || !c || c->has_init) return -1;

    fp = fopen(f, "r");
    if (!fp) {
        fprintf(stderr, "INITIATE: fopen file Error.\n");
        goto exit_err;
    }

    /* acquire bitmap header */
    if (sizeof(BMP_Head_t) != fread(&c->head, 1, sizeof(BMP_Head_t), fp)) {
        fprintf(stderr, "INITIATE: fread bitmap.head Error.\n");
        goto exit_err;
    }

    /* acquire bitmap map information */
    if (sizeof(BMP_MapInfo_t) != fread(&c->map_info, 1, sizeof(BMP_MapInfo_t), fp)) {
        fprintf(stderr, "INITIATE: fread bitmap.mapinfo Error.\n");
        goto exit_err;
    }

    /* judge bitmap format */
    if (c->head.identifier != ('M'<<8 | 'B')) {
        fprintf(stderr, "INITIATE: Is NOT bitmap format.\n");
        goto exit_err;
    }
    
    /* for now, only 24bits bitmap works well */
    if (c->map_info.bits_per_pixel != 24) {
        fprintf(stderr, "INITIATE: Is NOT 24-bit bitmap.\n");
        goto exit_err;
    }

    /* allocate buffer for image data */
    c->img_data_buf = (unsigned char *)malloc(c->map_info.data_size);
    if (!c->img_data_buf) {
        fprintf(stderr, "INITIATE: Can't allocate memory for image data buffer.\n");
        goto exit_err;
    }

    /* acquire bitmap data */
    if (c->map_info.data_size != fread(c->img_data_buf, 1, c->map_info.data_size, fp)) {
        fprintf(stderr, "INITIATE: fread bitmap.img_data Error.\n");
        goto exit_err;
    }

    c->has_init = 1;
    retval = 0;
    
exit_err:
    if (fp) fclose(fp);
    return retval;
}

int main(int argc, char* argv[])
{
    BMP_Container_t img_container;
        
    memset(&img_container, 0x0, sizeof(img_container));
    img_container.file_name = "source.bmp";
        
    if (BMP_Initiate(img_container.file_name, &img_container)) {
        return -1;
    }
    
    BMP_Rotate("rotate.bmp", &img_container);
    BMP_Mirror("mirror.bmp", &img_container);
    BMP_Gray("gray.bmp", &img_container);
    
    if (img_container.img_data_buf) free(img_container.img_data_buf);
    
    printf("Done.\n");
    return 0;
}


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载