C语言bmp图片读写,画点,画线

bmp文件信息头、文件头结构体:

#pragma pack(1)

typedef struct {
    uint16_t bfType;//位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为'BM'
    uint32_t bfSize;//BMP图像文件的大小
    uint16_t bfReserved1;//总为0
    uint16_t bfReserved2;//总为0
    uint32_t bfOffBits;//BMP图像数据的地址  54
    uint32_t biSize;//本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为28h字节=40字节
    uint32_t biWidth;// BMP图像的宽度,单位像素
    uint32_t biHeight;//总为0
    uint16_t biPlanes;//总为0
    uint16_t biBitCount;//BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色
    uint32_t biCompression;//压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定
    uint32_t biSizeImage;// BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足
    uint32_t biXPelsPerMeter;//水平分辨率,单位像素/m
    uint32_t biYPelsPerMeter;//垂直分辨率,单位像素/m
    uint32_t biClrUsed;//BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h=256
    uint32_t biClrImportant;//重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色
} BMPFILEHEADER, *bmpFileHead;

#pragma pack()

注意上面要使用内存对齐#pragma pack(1)    #pragma pack()

代码封装了五个接口函数:

int  bmp_load(BMP *pb, char *file);//读取图片
int  bmp_save(BMP *pb, char *file);//存储图片
void bmp_free(BMP *pb);//清除内存
void bmp_setpixel(BMP *pb, int x, int y, int r, int g, int b);//画点
void bmp_getpixel(BMP *pb, int x, int y, int *r, int *g, int *b);//获取点的rgb值

具体代码如下:

bmp.h

#ifndef __BMPFILE_H__
#define __BMPFILE_H__

typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#define TRUE 1

typedef struct{
    uint8_t *pData; // 图像数据
    int nImgW; // 图像宽度
    int nImgH; // 图像高度
    int nBits; // 1,4,8,24,32
    char bInit; // 是否已进行初始化,TRUE:已初始化。不能直接用指针来判断pData是否已初始化,因为pData的初始值不为NULL
// 也不能用(!bInit)来判断是否初始化,必须用(TRUE!=bInit)
} BMP;

int  bmp_load(BMP *pb, char *file);
int  bmp_save(BMP *pb, char *file);
void bmp_free(BMP *pb);
void bmp_setpixel(BMP *pb, int x, int y, int r, int g, int b);
void bmp_getpixel(BMP *pb, int x, int y, int *r, int *g, int *b);

#endif

bmp.c

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

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4);

#pragma pack(1)
typedef struct {
    uint16_t bfType;//位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为'BM'
    uint32_t bfSize;//BMP图像文件的大小
    uint16_t bfReserved1;//总为0
    uint16_t bfReserved2;//总为0
    uint32_t bfOffBits;//BMP图像数据的地址  54
    uint32_t biSize;//本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为28h字节=40字节
    uint32_t biWidth;// BMP图像的宽度,单位像素
    uint32_t biHeight;//总为0
    uint16_t biPlanes;//总为0
    uint16_t biBitCount;//BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色
    uint32_t biCompression;//压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定
    uint32_t biSizeImage;// BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足
    uint32_t biXPelsPerMeter;//水平分辨率,单位像素/m
    uint32_t biYPelsPerMeter;//垂直分辨率,单位像素/m
    uint32_t biClrUsed;//BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h=256
    uint32_t biClrImportant;//重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色
} BMPFILEHEADER, *bmpFileHead;

typedef struct tagRGBQUAD {
    uint8_t rgbBlue;
    uint8_t rgbGreen;
    uint8_t rgbRed;
    uint8_t rgbReserved;
} RGBQUAD, *PRGB;

#pragma pack()

int bmp_load(BMP *pb, char *file){
    BMPFILEHEADER bmp; //BMP文件头 信息头结构体

    FILE* fp; //指向文件的指针
    RGBQUAD *ipRGB = NULL;
    uint32_t LineBytes; // 每行的字节数
    uint32_t ImgBytesSize; // 图像总字节数
    uint32_t NumColors;
    int i;

    // 先释放图像空间
    if (pb->bInit == TRUE) {
        free(pb->pData);
    }
    pb->pData = NULL;

    // 打开文件
    fp = fopen(file, "rb");
    if (fp == NULL) {
        printf("fopen error\n");
        return -1;
    }

    //读取信息头、文件头
    //把指针fp所指向的文件的头信息写入bf(地址)
    if (fread(&bmp, sizeof(BMPFILEHEADER), 1, fp) == 0)
            {
        printf("fread error\n");
    }

    printf("bf.bfSize = %d\n", bmp.bfSize);
    printf("bi.biSize = %d\n", bmp.biSize);
    printf("bi.biWidth = %d\n", bmp.biWidth);
    printf("bi.biHeight = %d\n", bmp.biHeight);
    printf("bi.biBitCount = %d\n", bmp.biBitCount);
    printf("bi.bfOffBits = %d\n", bmp.bfOffBits);
// 计算行字节数和总字节数
    LineBytes = (uint32_t) WIDTHBYTES(bmp.biWidth * bmp.biBitCount)
    ; //计算位图的实际宽度并确保它为32的倍数
    ImgBytesSize = (uint32_t) LineBytes * bmp.biHeight;

    if (bmp.biClrUsed != 0) {
        NumColors = (uint32_t) bmp.biClrUsed;
    } else {
        switch (bmp.biBitCount) {
        case 1:
            NumColors = 2;
            break;
        case 4:
            NumColors = 16;
            break;
        case 8:
            NumColors = 256;
            break;
        case 24:
            NumColors = 0;
            break;
        case 32:
            NumColors = 0;
            break;
        }
    }

    //分配调色板内存
    if ((bmp.biBitCount != 24) && (bmp.biBitCount != 32)) {
        ipRGB = (RGBQUAD *) malloc(NumColors * sizeof(RGBQUAD));
        fread(ipRGB, sizeof(RGBQUAD), NumColors, fp);
    }

    // 初始化图像bi
    printf("ImgBytesSize = %d\n", ImgBytesSize); //2430000
    pb->pData = (uint8_t*) malloc(sizeof(uint8_t) * ImgBytesSize); // 分配图像内存, 外部释放
    if (pb->pData == NULL) {
        free(ipRGB);
        return -1;
    }
    pb->nBits = bmp.biBitCount;
    pb->nImgW = bmp.biWidth;
    pb->nImgH = bmp.biHeight;
    pb->bInit = TRUE;

    if ((bmp.biBitCount == 32) || (bmp.biBitCount == 24)) {
        //fseek(fp, 4, SEEK_CUR); //SEEK_CUR:表示文件的相对当前位置
        for (i = pb->nImgH - 1; i >= 0; --i) {
            fread(pb->pData + i * LineBytes, 1, LineBytes, fp);
        }
    } else {
        for (i = pb->nImgH - 1; i >= 0; --i) {
            fread(pb->pData + i * LineBytes, 1, LineBytes, fp);
        }
    }
    fclose(fp);
    fp = NULL;

    free(ipRGB);

    return 0;
}

int bmp_save(BMP *pb, char *file) {
    BMPFILEHEADER bmp; //BMP文件头  信息头结构体
    RGBQUAD *ipRGB = NULL;
    uint32_t NumColors;
    int i;
    uint32_t nLineBytes = (uint32_t) WIDTHBYTES(pb->nImgW * pb->nBits);

    FILE* fp = NULL;

    if ((!file) || (TRUE != pb->bInit)) {
        return -1;
    }

    // 写入另一个文件
    fp = fopen(file, "wb");

    memset(&bmp, 0, sizeof(bmp));
    *((char*) &(bmp.bfType)) = 'B';
    *(((char*) &(bmp.bfType)) + 1) = 'M';
    bmp.bfReserved1 = 0;
    bmp.bfReserved2 = 0;
    bmp.bfOffBits = sizeof(BMPFILEHEADER);
    bmp.bfSize = pb->nImgW * pb->nImgH * (pb->nBits >> 3) + bmp.bfOffBits;

    bmp.biSize = 40;
    bmp.biBitCount = pb->nBits;
    printf("bi.biBitCount = %d\n", bmp.biBitCount);
    bmp.biWidth = pb->nImgW;
    bmp.biHeight = pb->nImgH;
    bmp.biCompression = 0;
    bmp.biPlanes = 1;
    bmp.biClrUsed = 0;

    fwrite(&bmp, sizeof(BMPFILEHEADER), 1, fp);

    if (bmp.biClrUsed != 0) {
        NumColors = (uint32_t) bmp.biClrUsed;
    } else {
        switch (bmp.biBitCount) {
        case 1:
            NumColors = 2;
            break;
        case 4:
            NumColors = 16;
            break;
        case 8:
            NumColors = 256;
            break;
        case 24:
            NumColors = 0;
            break;
        case 32:
            NumColors = 0;
            break;
        }
    }

    //分配调色板内存
    if ((bmp.biBitCount != 24) && (bmp.biBitCount != 32)) {
        ipRGB = (RGBQUAD *) malloc(NumColors * sizeof(RGBQUAD));
        fread(ipRGB, sizeof(RGBQUAD), NumColors, fp);
    }

    if ((bmp.biBitCount != 24) && (bmp.biBitCount != 32)) {
        fwrite(ipRGB, sizeof(RGBQUAD), NumColors, fp);
        for (i = (bmp.biHeight) - 1; i >= 0; i--) {
            fwrite(pb->pData + nLineBytes * i, sizeof(uint8_t), nLineBytes, fp);
        }
    } else {
        for (i = (bmp.biHeight) - 1; i >= 0; i--) {
            fwrite(pb->pData + nLineBytes * i, sizeof(uint8_t), nLineBytes,fp);
        }
    }

    fclose(fp);
    fp = NULL;
    free(ipRGB);
    return 0;
}

void bmp_free(BMP *pb){
    if (pb != NULL) {
        free(pb);
        pb = NULL;
    }
}

void bmp_setpixel(BMP *pb, int x, int y, int r, int g, int b) {
    pb->pData[y * pb->nImgW * 3 + x * 3 + 0] = b;
    pb->pData[y * pb->nImgW * 3 + x * 3 + 1] = g;
    pb->pData[y * pb->nImgW * 3 + x * 3 + 2] = r;
}

void bmp_getpixel(BMP *pb, int x, int y, int *r, int *g, int *b) {
    *b = pb->pData[y * pb->nImgW * 3 + x * 3 + 0];
    *g = pb->pData[y * pb->nImgW * 3 + x * 3 + 1];
    *r = pb->pData[y * pb->nImgW * 3 + x * 3 + 2];
}

int main(void) {
    char filename1[] = "./1.bmp";
    char filename2[] = "./2.bmp";

    BMP* pmi = (BMP *) malloc(sizeof(BMP));
    if(pmi == NULL){
        printf("malloc error\n");
    }

    if ((bmp_load((BMP *)&pmi,filename1)) < 0) {
        printf("bmp_load error\n");
    }

    //测试画点
      for (int y = 50; y < 60; y++) {
          for (int x = 50; x < 100; x++) {
              bmp_setpixel((BMP *)&pmi, x, y, 0, 0, 255);
          }
      }
    if ((bmp_save((BMP *)&pmi,filename2)) < 0) {
        printf("bmp_save error\n");
    }

    bmp_free(pmi);

    return EXIT_SUCCESS;
}

上面的代码是笔者实现的,不足是肯定有的,下面的代码是老师给的参考代码,可以实现上面的功能,还可以画框。

 bmpfile.c:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bmpfile.h"

#define ALIGN(a, b) (((a) + (b) - 1) & ~((b) - 1))
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
#define _TEST2_ 1
//++ for bmp file ++//
// 内部类型定义
#pragma pack(1)

//typedef struct {
//	uint16_t  bfType;
//	uint32_t  bfSize;
//	uint16_t  bfReserved1;
//	uint16_t  bfReserved2;
//	uint32_t  bfOffBits;
//	uint32_t  biSize;
//	uint32_t  biWidth;
//	uint32_t  biHeight;
//	uint16_t  biPlanes;
//	uint16_t  biBitCount;
//	uint32_t  biCompression;
//	uint32_t  biSizeImage;
//	uint32_t  biXPelsPerMeter;
//	uint32_t  biYPelsPerMeter;
//	uint32_t  biClrUsed;
//	uint32_t  biClrImportant;
//} BMPFILEHEADER;
	
typedef struct {
	uint16_t bfType;//位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为'BM'
	uint32_t bfSize;//BMP图像文件的大小
	uint16_t bfReserved1;//总为0
	uint16_t bfReserved2;//总为0
	uint32_t bfOffBits;//BMP图像数据的地址  54
	uint32_t biSize;//本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为28h字节=40字节
	uint32_t biWidth;// BMP图像的宽度,单位像素
	uint32_t biHeight;//总为0
	uint16_t biPlanes;//总为0
	uint16_t biBitCount;//BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色
	uint32_t biCompression;//压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定
	uint32_t biSizeImage;// BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足
	uint32_t biXPelsPerMeter;//水平分辨率,单位像素/m
	uint32_t biYPelsPerMeter;//垂直分辨率,单位像素/m
	uint32_t biClrUsed;//BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h=256
	uint32_t biClrImportant;//重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色
} BMPFILEHEADER, *bmpFileHead;
#pragma pack()

/* 函数实现 */
int bmp_load(BMP *pb, char *file)
{
    BMPFILEHEADER header = {0};
    FILE         *fp     = NULL;
    uint8_t      *pdata  = NULL;
    int           i;

    fp = fopen(file, "rb");
    if (!fp) return -1;

    fread(&header, sizeof(header), 1, fp);
    pb->width  = header.biWidth;
    pb->height = header.biHeight;
    pb->stride = ALIGN(header.biWidth * 3, 4);//琛屽瓧鑺傛暟pb->stride 
    //鍦?4浣峛mp鍥句腑锛屼竴涓儚绱犳槸涓€涓偣锛岃€屼竴涓儚绱犳湁24浣嶏紝鍗?涓瓧鑺傘€?
    pb->cdepth = 24;
    pb->pdata  = malloc(pb->stride * pb->height);
    if (pb->pdata) {
        pdata  = (uint8_t*)pb->pdata + pb->stride * pb->height;//鎸囧悜鏈€鍚庝竴琛?
        for (i=0; i<pb->height; i++) {
            pdata -= pb->stride;//鍚戜笂
            fread(pdata, pb->stride, 1, fp);//鎸夎璇诲彇
        }
    }

    fclose(fp);
    return pb->pdata ? 0 : -1;
}

int bmp_create(BMP *pb)
{
    pb->stride = ALIGN(pb->width * (pb->cdepth / 8), 4);
	//鍍忕礌閫氬父鐢ㄦ潵琛ㄧず浣嶅浘涓殑涓€涓偣銆備竴涓瓧鑺傚寘鍚?涓瘮鐗癸紝
	//鍦ㄥ鏉備竴浜涚殑浣嶅浘锛堜緥濡?4浣嶇湡褰╄壊BMP锛夛紝涓€涓儚绱犵敱涓変釜瀛楄妭鏋勬垚锛屾瘡涓瓧鑺傚垎鍒〃绀?56绉嶇姸鎬佺殑绾€佺豢銆佽摑銆傝繖鏍峰彲浠ヨ〃鐜扮浉褰撲赴瀵岀殑鑹插僵銆?
    pb->pdata  = calloc(1, pb->width * pb->stride);
    return pb->pdata ? 0 : -1;
}

int bmp_save(BMP *pb, char *file)
{
    BMPFILEHEADER header = {0};
    FILE         *fp     = NULL;
    uint8_t      *pdata;
    int           i;

    header.bfType     = ('B' << 0) | ('M' << 8);
    header.bfSize     = sizeof(header) + pb->stride * pb->height;
    header.bfOffBits  = sizeof(header);
    header.biSize     = 40;
    header.biWidth    = pb->width;
    header.biHeight   = pb->height;
    header.biPlanes   = 1;
    header.biBitCount = pb->cdepth;
    header.biSizeImage= pb->stride * pb->height;

    fp = fopen(file, "wb");
    if (fp) {
        fwrite(&header, sizeof(header), 1, fp);
        pdata = (uint8_t*)pb->pdata + pb->stride * pb->height;
        for (i=0; i<pb->height; i++) {
            pdata -= pb->stride;
            fwrite(pdata, pb->stride, 1, fp);//鎸夎鍐欏叆
        }
        fclose(fp);
    }

    return fp ? 0 : -1;
}

void bmp_free(BMP *pb)
{
    if (pb->pdata) {
        free(pb->pdata);
        pb->pdata = NULL;
    }
    pb->width  = 0;
    pb->height = 0;
    pb->stride = 0;
    pb->cdepth = 0;
}

void bmp_setpixel(BMP *pb, int x, int y, int r, int g, int b)//x,y琛ㄧず鍦ㄥ摢涓儚绱犵偣
{
    uint8_t *pbyte = pb->pdata;
    if (x < 0 || y < 0 || x >= pb->width || y >= pb->height) return;
//  r = r < 0 ? 0 : r < 255 ? r : 255;
//  g = g < 0 ? 0 : g < 255 ? g : 255;
//  b = b < 0 ? 0 : b < 255 ? b : 255;
    pbyte[x * (pb->cdepth / 8) + 0 + y * pb->stride] = b;//pb->cdepth鍍忕礌浣嶆暟 pb->cdepth = 24;x鏄儚绱犵偣鐨勬í鍧愭爣锛?4浣峛mp涓竴涓儚绱犵偣涓変釜瀛楄妭銆?
    pbyte[x * (pb->cdepth / 8) + 1 + y * pb->stride] = g;//pb->stride 琛屽瓧鑺傛暟 pb->stride = ALIGN(header.biWidth * 3, 4);
    pbyte[x * (pb->cdepth / 8) + 2 + y * pb->stride] = r;//header.biWidth BMP鍥惧儚鐨勫搴︼紝鍗曚綅鍍忕礌

void bmp_getpixel(BMP *pb, int x, int y, int *r, int *g, int *b)
{
    uint8_t *pbyte = pb->pdata;
    if (x < 0 || y < 0 || x >= pb->width || y >= pb->height) { *r = *g = *b = 0; return; }
    *b = pbyte[x * (pb->cdepth / 8) + 0 + y * pb->stride];
    *g = pbyte[x * (pb->cdepth / 8) + 1 + y * pb->stride];
    *r = pbyte[x * (pb->cdepth / 8) + 2 + y * pb->stride];
}

void bmp_dotmatrix(BMP *pb, int x, int y, int r, int g, int b, char *matrix, int mw, int mh)
{
    int  i;
    mw = ALIGN(mw, 8);
    for (i=0; i<mw * mh; i++) {
        if (matrix[i / 8] & (1 << (7 - i % 8))) bmp_setpixel(pb, x + i % mw, y + i / mw, r, g, b);
    }
}

void bmp_drawtext(BMP *pb, int x, int y, int r, int g, int b, char *text, char *ascfont, int ascw, int asch, char *hzfont, int hzw, int hzh)
{
    FILE *fpasc = fopen(ascfont, "rb");
    FILE *fphz  = fopen(hzfont , "rb");
    int   szasc = ALIGN(ascw, 8) * asch / 8;
    int   szhz  = ALIGN(hzw , 8) * hzh  / 8;
    int   cx = x, cy = y, dx, mw, mh;
    char *matbuf= malloc(MAX(szhz, szasc));
    if (!matbuf) {
        printf("bmp_drawtext failed to allocate buffer !\n");
        return;
    }
    while (*text) {
        if (text[0] == '\n') {
            cx  = x;
            cy += MAX(asch, hzh) + hzh / 4;
            text++; continue;
        } else if ((uint8_t)text[0] < 0xA1) {
            mw = ascw, mh = asch, dx = ascw;
            if (fpasc) {
                fseek(fpasc, *text * szasc, SEEK_SET);
                fread(matbuf, 1, szasc, fpasc);
            } else goto next;
        } else {
            mw = hzw , mh = hzh , dx = hzw;
            if (text[1] == '\0') break;
            else if (fphz && (uint8_t)text[1] >= 0xA1) {
                int qm = (uint8_t)text[0] - 0xA1, wm = (uint8_t)text[1] - 0xA1;
                fseek(fphz, (qm * 94 + wm) * szhz, SEEK_SET);
                fread(matbuf, 1, szhz, fphz);
                text++;
            } else goto next;
        }
        bmp_dotmatrix(pb, cx, cy + MAX(asch, hzh) - mh, r, g, b, matbuf, mw, mh);
next:   cx += dx, text++;
    }
    if (fpasc) fclose(fpasc);
    if (fphz ) fclose(fphz );
    free(matbuf);
}

void bmp_fillrect(BMP *pb, int x, int y, int w, int h, int r, int g, int b, int alpha)
{
    int fr = r, fg = g, fb = b, br, bg, bb, i, j;
    for (i=0; i<h; i++) {
        for (j=0; j<w; j++) {
            if (alpha) {
                bmp_getpixel(pb, x + j, y + i, &br, &bg, &bb);
                fr = r + alpha * (br - r) / 255;
                fg = g + alpha * (bg - g) / 255;
                fb = b + alpha * (bb - b) / 255;
            }
            bmp_setpixel(pb, x + j, y + i, fr, fg, fb);
        }
    }
}

void bmp_bitblt(BMP *pbdst, int dstx, int dsty, BMP *pbsrc, int srcx, int srcy, int w, int h)
{
    int r, g, b, i, j;
    for (i=0; i<h; i++) {
        for (j=0; j<h; j++) {
            bmp_getpixel(pbsrc,srcx + j, srcy + i, &r, &g, &b);
            bmp_setpixel(pbdst, dstx + j, dstx + i,  r,  g,  b);
        }
    }
}

#if _TEST1_
int main(int argc, char *argv[])
{
    BMP bmp24 = {};
    BMP bmp32 = {};
    int x, y, r, g, b;
    char file[256];

    if (argc < 2) {
        printf("\n");
        printf("tool for convert 24bit bitmap to 32bit\n\n");
        printf("usage:\n");
        printf("  bmp24to32 bmpfile \n\n");
        return 0;
    }

    bmp_load(&bmp24, argv[1]);
    bmp32.width  = bmp24.width;
    bmp32.height = bmp24.height;
    bmp32.cdepth = 32;
    bmp_create(&bmp32);

    for (y=0; y<bmp24.height; y++) {
        for (x=0; x<bmp24.width; x++) {
            bmp_getpixel(&bmp24, x, y, &r, &g, &b);
            bmp_setpixel(&bmp32, x, y,  r,  g,  b);
        }
    }

    snprintf(file, sizeof(file), "%s.32", argv[1]);
    bmp_save(&bmp32, file);

    bmp_free(&bmp24);
    bmp_free(&bmp32);
}
#endif

#if _TEST2_
int main(void)
{
	BMP bmp1 = {0}, bmp2 = {0};
	bmp_load(&bmp1, "test.bmp");
	bmp_load(&bmp2, "bb.bmp"  );
	bmp_bitblt  (&bmp1, 20, 20, &bmp2, 0, 0, bmp2.width, bmp2.height);
	bmp_fillrect(&bmp1, 200, 150, 300, 80, 0, 0, 255, 120);
	bmp_drawtext(&bmp1, 220, 160, 255, 255, 255, "hello 中英文混合文本输出\n中英文混合文本输出 hello", "ASC0814.dat", 8, 14, "HZK1616.dat", 16, 16);
	bmp_save(&bmp1, "out.bmp");
	bmp_free(&bmp1);
	bmp_free(&bmp2);
	return 0;
}
#endif


bmpfile.h:

#ifndef __BMPFILE_H__
#define __BMPFILE_H__

/* BMP 对象的类型定义 */
typedef struct {
    int   width;   /* 宽度 */
    int   height;  /* 高度 */
    int   stride;  /* 行字节数 */
    int   cdepth;  /* 像素位数 */
    void *pdata;   /* 指向数据 */
} BMP;

int  bmp_load(BMP *pb, char *file);
int  bmp_save(BMP *pb, char *file);
void bmp_free(BMP *pb);
void bmp_setpixel (BMP *pb, int x, int y, int  r, int  g, int  b);
void bmp_getpixel (BMP *pb, int x, int y, int *r, int *g, int *b);
void bmp_dotmatrix(BMP *pb, int x, int y, int r, int g, int b, char *matrix, int mw, int mh);
void bmp_drawtext (BMP *pb, int x, int y, int r, int g, int b, char *text, char *ascfont, int ascw, int asch, char *hzfont, int hzw, int hzh);
void bmp_fillrect (BMP *pb, int x, int y, int w, int h, int r, int g, int b, int alpha);
void bmp_bitblt   (BMP *pbdst, int dstx, int dsty, BMP *pbsrc, int srcx, int srcy, int w, int h);

#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值