1. 程式人生 > >linux下使用open(),write(),給bmp圖片打馬賽克

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的效果。