Linux 图片全屏缩放 c,RGB源数据操作: 实现图片放大、缩小

一、运行环境介绍

Linux系统: Redhat6.3 (32位)

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

二、功能介绍

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

三、核心代码

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

#include

#include

#include

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

{

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

1c07d311aa833feb9c71533cb360a3cf.png

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值