linux下使用open(),write(),给bmp图片打马赛克

本程序用于在linux下使用文件操作对bmp图片进行打马赛克,效果很不错。

对于bmp格式,只需要知道这两点,1,偏移为18byte的地方保存了bmp图片的宽度和高度,分别占4byte,2,偏移为54byte的地方为图片的数据区,若为24位彩色图,则一个像素占3byte空间。程序如下:

/*===============================================================
*   Copyright (C) 2017 All rights reserved.
*   
*   文件名称:mask.c
*   创 建 者:no_play
*   创建日期:2017年07月25日
*   描    述:
*
*   更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef struct color
{
	unsigned char B;
	unsigned char G;
	unsigned char R;
}COLOR;

int main(int argc,char *argv[]) 
{
	
	if(8 != argc)
	{
		printf("Usage:%s <src file> <dst file> <xstart> <ystart> <mask_width> <mask_height> <mask_len>\n",argv[0]);
		return -1;
	}

	int src = open(argv[1],O_RDWR);
	if(-1 == src)
	{
		perror(argv[1]);
		return -1;
	}
	int dst = open(argv[2],O_RDWR | O_CREAT | O_TRUNC, 0666);
	if(-1 == dst)
	{
		perror(argv[2]);
		return -1;
	}

	int n;
	
	char buff[1024*1024*4]={0}; /* 定义4M大小 */
	n = read(src, buff, sizeof buff); /* 将文件内容放入buff中,后面改变像素时直接在buff中改变,速度更快 */
	
	int *pwidth = (int *)&buff[18];    /* bmp格式将宽度和高度存放在从18字节开始的地方 */
	int *pheight = (int *)&buff[18+4];

	int width = *pwidth;
	int height = *pheight;
	int xoff = atoi(argv[3]);
	int yoff = atoi(argv[4]);
	int mask_width = atoi(argv[5]);
	int mask_height = atoi(argv[6]);
	int mask_len = atoi(argv[7]);

	int cnt=0,num=0;
	COLOR temp[100],color;/* 保存三原色值 */
	int lable = 54; /* 标签,指示当前读取位置,由于bmp格式图片前54字节为头部,所以指向54 */
	lable = lable + 3*(width*(height-yoff-mask_height) + xoff);
	int i,j;
	for(i=0;i<mask_height;i++)
	{
		for(j=0;j<mask_width;j++)
		{
			if(j%mask_len == 0)  /* 将10X10个像素点变成一个颜色 */
			{
				if(i%mask_len == 0)
				{
					color.B = buff[lable];
					color.G = buff[lable + 1];
					color.R = buff[lable + 2];
					temp[cnt] = color; /* 保存前一行的像素值 */
					cnt++;
				}
				else
				{
					color = temp[num];/* 在高度为10的像素内使用一个颜色值 */
					num++;
				}
			}
			buff[lable] = color.B;
			buff[lable + 1] = color.G;
			buff[lable + 2] = color.R;
			lable += 3;
		}
		lable += 3*(width-mask_width);
		cnt = 0;
		num = 0;
	}

	write(dst, buff, n); /* 将打码后的buff写入目标文件 */

	close(src);
	close(dst);
	return 0;
}
参数argv的含义用一张图片来解释:


如果有张bmp图片名为1.bmp,将上面的程序编译为a.out,执行下面的命令的含义就是将1.bmp的x=100,y=100像素的地方开始,长度为150,宽度为150的一个矩形区域打上马赛克,打马赛克的程度为5,即5个像素点变成一个颜色。

./a.out 1.bmp 1_mask.bmp 100 100 150 150 10

下面是两张mask_len为10和mask_len为5的图片:

mask_len=10的效果。

mask_len=5的效果。


  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值