Markdown编辑器 正则表达式 后端面试 debugging flexbox vue开发 vue自定义组件 后台模板 java后台框架 oracle无效的列索引 cpm计算 matlab对数函数 oracle添加索引 oracle重命名表名 matlab自然对数 oracle给表增加字段 idea批量替换快捷键 input函数python python匹配字符串 python安装模块 java在线学习 java怎么使用 linux镜像安装 乱码查看器 ps怎么插入表格 su版本转换器 ae脚本管理器 凯恩与林奇2下载 一羽月土米水日古余打一成语 phpword 社区网格化管理平台 苹果手机验机软件 ps反向选择的快捷键 winfax linux格式化硬盘 renderpartial 通灵学院在哪 贪吃蛇c语言代码 失心迷宫怎么打 预测未来长相的软件
当前位置: 首页 > 学习教程  > 编程语言

对RGB源图片数据进行缩放

2020/8/11 20:57:35 文章标签:

一、运行环境介绍

Linux系统: Redhat6.3 (32位)

gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

二、功能介绍

打开一张BMP图片,读取RGB源数据进行缩放再生成新的BMP图片。

三、核心代码

由于处理的是BMP图片数据,传入的缩放后的图片宽度需要是4的倍数.

缩放算法参考: http://blog.chinaunix.net/uid-22915173-id-2185545.html

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

int PicZoom(unsigned char *s_buff,unsigned int s_width,unsigned int s_height,unsigned char *buff,unsigned int width,unsigned int height);
void *my_memcpy(void *v_dst,const void *v_src,unsigned char c);

#pragma pack(1)   /* 必须在结构体定义之前使用,这是为了让结构体中各成员按1字节对齐 */
/*需要文件信息头:14个字节 */
struct BITMAPFILEHEADER
{
	unsigned short bfType;      //保存图片类似。 'BM'
	unsigned long  bfSize;      //图片的大小
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned long  bfOffBits;  //RGB数据偏移地址
};

/* 位图信息头 */
struct BITMAPINFOHEADER { /* bmih */
	unsigned long  biSize;      //结构体大小
	unsigned long  biWidth;		//宽度
	unsigned long  biHeight;	//高度
	unsigned short biPlanes;
	unsigned short biBitCount;	//颜色位数
	unsigned long  biCompression;
	unsigned long  biSizeImage;
	unsigned long  biXPelsPerMeter;
	unsigned long  biYPelsPerMeter;
	unsigned long  biClrUsed;
	unsigned long  biClrImportant;
};

/*
图片放大与缩小示例
*/
int main(int argc,char *argv[])
{
	struct BITMAPFILEHEADER src_head;  //源文件头数据
	struct BITMAPINFOHEADER src_info;  //源文件参数结构
	struct BITMAPFILEHEADER new_head;  //新文件头数据
	struct BITMAPINFOHEADER new_info;  //新文件参数结构
	unsigned int new_Width;			   //缩放后的宽度
	unsigned int new_Height;		   //缩放后的高度
	unsigned char *new_buff;           //存放新图片的数据
	unsigned char *src_buff;           //存放源图片的数据
	unsigned int cnt=0;

    if(argc!=5)
    {
        printf("参数格式: ./a.out <原图片名称> <新图片名称> <缩放后宽度> <缩放后高度>\n");
        printf("例如: ./a.out src.bmp new.bmp 80 80 \n");
        return 0;
    }
	/*1. 打开图片文件*/
	FILE *src_file=fopen(argv[1],"rb");
	FILE *new_file=fopen(argv[2],"wb");
	if(src_file==NULL||new_file==NULL)
	{
		printf("%s 源文件打开失败!\r\n",argv[1]);
		return;
	}
	
	/*2. 读取源图片参数*/
	fread(&src_head,sizeof(struct BITMAPFILEHEADER),1,src_file);
	fread(&src_info,sizeof(struct BITMAPINFOHEADER),1,src_file);
	printf("源图片尺寸:w=%d h=%d\r\n",src_info.biWidth,src_info.biHeight);

	/*3. 获取新图片的尺寸*/
    new_Width=atoi(argv[3]);
    new_Height=atoi(argv[4]);
	printf("新图片尺寸:w=%d h=%d\r\n",new_Width,new_Height);

	/*4. 申请存放图片数据的空间*/
	src_buff=malloc(src_info.biWidth*src_info.biHeight*3);
	new_buff=malloc(new_Width*new_Height*3);
	if(new_buff==NULL||src_buff==NULL)
	{
		printf("malloc申请空间失败!\r\n");
		return -1;
	}

	/*5. 读取源图片RGB数据*/
	fseek(src_file,src_head.bfOffBits,SEEK_SET); //移动文件指针到RGB数据位置
	fread(src_buff,1,src_info.biWidth*src_info.biHeight*3,src_file); //读取源数据

	/*6. 缩放图片*/
	if(PicZoom(src_buff,src_info.biWidth,src_info.biHeight,new_buff,new_Width,new_Height))
	{
		printf("图片缩放处理失败!\r\n");
		return -1;
	}

	/*7. 写入新图片数据*/
	//填充文件头
	memset(&new_head,0,sizeof(struct BITMAPFILEHEADER));
	new_head.bfType=0x4d42;
	new_head.bfSize=54+new_Width*new_Height*3;
	new_head.bfOffBits=54;
	//填充文件参数
	memset(&new_info,0,sizeof(struct BITMAPINFOHEADER));
	new_info.biSize=sizeof(struct BITMAPINFOHEADER);
	new_info.biWidth=new_Width;
	new_info.biHeight=new_Height;
	new_info.biPlanes=1;
	new_info.biBitCount=24;
	//写入文件数据
	fwrite(&new_head,sizeof(struct BITMAPFILEHEADER),1,new_file);
	fwrite(&new_info,sizeof(struct BITMAPINFOHEADER),1,new_file);
	fseek(new_file,new_head.bfOffBits,SEEK_SET); //移动文件指针到RGB数据位置
	cnt=fwrite(new_buff,1,new_info.biWidth*new_info.biHeight*3,new_file); //写数据

	/*8. 关闭图片文件*/
	fclose(new_file);
	fclose(src_file);

	printf("%s 新图片创建成功! 路径:程序运行路径下\r\n",argv[2]);
	return 0;
}


/**********************************************************************
* 函数名称: PicZoom
* 功能描述: 近邻取样插值方法缩放图片
*            注意该函数会分配内存来存放缩放后的图片,用完后要用free函数释放掉
*            "近邻取样插值"的原理请参考网友"lantianyu520"所著的"图像缩放算法"
* 输入参数:  ptOriginPic - 内含原始图片的象素数据
*             ptZoomPic    - 内含缩放后的图片的象素数据
* 输出参数: 无
* 返 回 值: 0 - 成功, 其他值 - 失败
***********************************************************************/
int PicZoom(unsigned char *ptOriginPic_aucPixelDatas,unsigned int ptOriginPic_iWidth,unsigned int ptOriginPic_iHeight,unsigned char *ptZoomPic_aucPixelDatas,unsigned int ptZoomPic_iWidth,unsigned int ptZoomPic_iHeight)
{
	unsigned int ptOriginPic_iLineBytes=ptOriginPic_iWidth*3; //一行的字节数
	unsigned int ptZoomPic_iLineBytes=ptZoomPic_iWidth*3;  //一行的字节数

	unsigned long dwDstWidth=ptZoomPic_iWidth;
	unsigned long* pdwSrcXTable;
	unsigned long x;
	unsigned long y;
	unsigned long dwSrcY;
	unsigned char *pucDest;
	unsigned char *pucSrc;
	unsigned long dwPixelBytes=3; //像素字节
	pdwSrcXTable=malloc(sizeof(unsigned long) * dwDstWidth);
	if(NULL==pdwSrcXTable)
	{
		return -1;
	}

	for(x=0; x < dwDstWidth; x++)//生成表 pdwSrcXTable
	{
		pdwSrcXTable[x]=(x*ptOriginPic_iWidth/ptZoomPic_iWidth);
	}

	for(y=0; y < ptZoomPic_iHeight; y++)
	{
		dwSrcY=(y * ptOriginPic_iHeight/ptZoomPic_iHeight);

		pucDest=ptZoomPic_aucPixelDatas + y * ptZoomPic_iLineBytes;
		pucSrc=ptOriginPic_aucPixelDatas+dwSrcY * ptOriginPic_iLineBytes;

		for(x=0; x <dwDstWidth; x++)
		{
			my_memcpy(pucDest+x*dwPixelBytes,pucSrc+pdwSrcXTable[x]*dwPixelBytes,dwPixelBytes);
		}
	}

	free(pdwSrcXTable);
	return 0;
}

/*
函数功能:内存拷贝函数
*/
void *my_memcpy(void *v_dst,const void *v_src,unsigned char c)
{
	const char *src=v_src;
	char *dst=v_dst;
	while(c--)*dst++=*src++;
	return v_dst;
}

四、运行示例

[wbyq@wbyq linux_c]$ gcc app.c 
[wbyq@wbyq linux_c]$ ./a.out 
参数格式: ./a.out <原图片名称> <新图片名称> <缩放后宽度> <缩放后高度>
例如: ./a.out src.bmp new.bmp 80 80 
[wbyq@wbyq linux_c]$ ./a.out 666.bmp 1.bmp 80 80
源图片尺寸:w=800 h=383
新图片尺寸:w=80 h=80
1.bmp 新图片创建成功! 路径:程序运行路径下
[wbyq@wbyq linux_c]$ eog 1.bmp 

 

下面公众号有全套的单片机、QT、C++、C语言、物联网相关的教程,欢迎关注:

 


本文链接:
http://www.dtmao.cc/news_show_100447.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?