【C语言】图像处理-揭秘电影特效,随心所欲,合成图像

本文介绍如何使用C语言进行图像处理,通过实例讲解图像合成,涉及位图文件结构、预设参数、位图信息头结构、像素信息等,带领读者理解图像处理的基本原理和操作。
摘要由CSDN通过智能技术生成

20200705@学习C语言第13天
严正声明,这篇文章属于汇编整理型,整理部分属于原创。参考自北京理工大学MOOC公开课,以及百科、博文等资料,已经在相应处附上链接。

图像处理实例

学习C语言最重要的就是要会应用到实践中去,图像处理就是一个非常典型的应用。在别人还在折腾ps蒙板时,你一秒不到就可以实现图片的合成,并且只要稍稍修改代码就可以实现更多样的处理。这到底是怎样做到的呢???来和初学第13天的小学渣一起看看吧。
我们要实现的目的是把这两张图片合成:
在这里插入图片描述
图1(图片来源于MOOC北京理工大学公开课)
在这里插入图片描述
图2(图片来源于MOOC北京理工大学公开课)

要做这件事情,我们首先了解一下图像文件的特点:
图像文件结构(File structure of images)一般的图像文件结构主要都包含有文件头、文件体和文件尾等三部分。
文件头的主要内容包括产生或编辑该图像文件的软件的信息以及图像本身的参数。这些参数必须完整地描述图像数据的所有特征,因此是图像文件中的关键数据。
文件体主要包括图像数据以及颜色变换查找表或调色板数据。这部分是文件的主体,对文件容量的大小起决定作用。如果是真彩色图像,则无颜色变换查找表或调色板数据,对于256色的调色板,每种颜色值用24 bit表示,则调色板的数据长度为256×3(Byte)。
文件尾可包含一些用户信息。文件尾是可选项,有的文件格式不包括这部分内容。

代码很长,不着急,我们逐条分析

代码1

// forclass1.cpp : Defines the entry point for the console application.
//
#include "stdio.h"
#include "malloc.h"
#include "memory.h"
#include "math.h"
typedef unsigned long     DWORD;
typedef unsigned short      WORD;
typedef unsigned char       BYTE;
typedef long LONG;
#pragma pack (2)
 
#define PAI 3.1415926
 
typedef struct tagBITMAPFILEHEADER {
    // bmfh
    WORD    bfType;             //TYPE == BM 
    DWORD   bfSize;              //文件大小 
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;           //图像像素起始位置 
} BITMAPFILEHEADER;
 
typedef struct tagBITMAPINFOHEADER{
    
    DWORD  biSize;                //文件大小 
    LONG   biWidth;
    LONG   biHeight;
    WORD   biPlanes;
    WORD   biBitCount;
    DWORD  biCompression;
    DWORD  biSizeImage;
    LONG   biXPelsPerMeter;
    LONG   biYPelsPerMeter;
    DWORD  biClrUsed;
    DWORD  biClrImportant;
} BITMAPINFOHEADER;
 
typedef struct tagRGBQUAD {
   
    BYTE    rgbBlue;
    BYTE    rgbGreen;
    BYTE    rgbRed;
    BYTE    rgbReserved;
} RGBQUAD;
 
struct BMPStruct
{
   
    BITMAPFILEHEADER fileHeader;   //文件头 
    BITMAPINFOHEADER bmphead;         //图像头 
    int lineByte;          //图像的实际宽度
    RGBQUAD *pColorTable;  //颜色表指针
    unsigned char *pBmpBuf;   //读入图像数据的指针
};
 
BMPStruct myBMP[3];
 
bool readBmp(char *bmpName, BMPStruct* curBMP)
{
   
    FILE *fp=fopen(bmpName,"rb");//二进制读方式打开指定的图像文件
    if(fp==0) return 0;
    //跳过位图文件头结构BITMAPFILEHEADER
    fread(&curBMP->fileHeader, sizeof(BITMAPFILEHEADER), 1,fp); 
    //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
    fread(&curBMP->bmphead, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高、每像素所占位数等信息
    curBMP->lineByte=(curBMP->bmphead.biWidth * curBMP->bmphead.biBitCount/8+3)/4*4;//灰度图像有颜色表,且颜色表表项为256
    if(curBMP->bmphead.biBitCount == 8)
    {
   
        //申请颜色表所需要的空间,读颜色表进内存
        curBMP->pColorTable=new RGBQUAD[256];
        fread(curBMP->pColorTable,sizeof(RGBQUAD),256,fp);
    }
    //申请位图数据所需要的空间,读位图数据进内存
    //curBMP->pBmpBuf=new unsigned char[curBMP->lineByte * curBMP->bmphead.biHeight];
    curBMP->pBmpBuf = (unsigned char *)malloc(curBMP->lineByte * curBMP->bmphead.biHeight);
    fread(curBMP->pBmpBuf,1,curBMP->lineByte * curBMP->bmphead.biHeight,fp);
    fclose(fp);//关闭文件
    return 1;//读取文件成功
}
 
bool saveBmp(char *bmpName, BMPStruct* curBMP)
{
   
    FILE *fp=fopen(bmpName,"wb");//二进制写方式打开指定的图像文件
    if(fp==0) return 0;
    //跳过位图文件头结构BITMAPFILEHEADER
    fwrite(&curBMP->fileHeader, sizeof(BITMAPFILEHEADER), 1,fp); 
    //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
    fwrite(&curBMP->bmphead, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高、每像素所占位数等信息
    if(curBMP->bmphead.biBitCount == 8)
    {
   
        //申请颜色表所需要的空间,读颜色表进内存
        curBMP->pColorTable=new RGBQUAD[256];
        fwrite(curBMP->pColorTable,sizeof(RGBQUAD),256,fp);
    }
    //申请位图数据所需要的空间,读位图数据进内存
    fwrite(curBMP->pBmpBuf,1,curBMP->lineByte * curBMP->bmphead.biHeight,fp);
    fclose(fp);//关闭文件
    return 1;//读取文件成功
}
 
int compose(BMPStruct mybmp[3])
{
   
    if (myBMP[0].bmphead.biHeight < myBMP[1].bmphead.biHeight || myBMP[0].bmphead.biWidth < myBMP[1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值