`
intl-bcds
  • 浏览: 79830 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

图片生成小程序

阅读更多

    (edit by king)由于性能测试需要,需要准备大量不相同的图片(图片md5值不同),为了方便的创建这些图片,写了个小程序来完成这个工作。

    这个程序最初的算法是生成一张指定长和宽的图片,然后一个个像素置成特定的颜色。因为最终要生成jpg文件,这样的做法,会导致生成的图片普遍比较小,最终确定为从参数中获得一个种子文件,然后对每个像素进行反色处理。

    主要的计算方法如下:

 

jpgInFile = fopen(param_p->fileName, "rb");
	if(jpgInFile == NULL)
	{
		perror("open seed file");
		return NULL;
	}

	im = gdImageCreateFromJpeg(jpgInFile);
	fclose(jpgInFile);
	width = gdImageSX(im);
	height = gdImageSY(im);
	pch = strrchr(param_p->fileName, '.');
	strncpy(fileBase, param_p->fileName, pch - param_p->fileName);

	for(n = param_p->start; n < param_p->end; ++n)
	{
	  color = gdImageGetPixel(im, n % width, (n / width) % height);
	  revertColor = gdImageColorAllocate(im, 0xFF - gdImageRed(im, color), 
			  0xFF - gdImageGreen(im, color), 0xFF - gdImageBlue(im, color));
	  gdImageSetPixel(im, n % width, (n / width) % height, revertColor);
	  
	  sprintf(fileName, "%s%d.jpg", fileBase, n);
	  jpgOutFile = fopen(fileName, "wb");
	  gdImageJpeg(im, jpgOutFile, 60);

	  fclose(jpgOutFile);
	}

 反色的方法很简单,分别用0xFF减去像素点的RGB分色就可以了。这里使用了gd库来操作图片,具体gd库的API,可以看http://www.libgd.org/Reference

    还有个问题,就是“大量”。刚开始还在纠结于用多线程还是多进程,看了下发现多进程非常不便于任务分派,最后还是决定是用多线程来加快图片的创建。

先定义一个结构来保存传递给线程函数的参数:

 

typedef struct
{
	char *fileName;
	int start;
	int end;
}param;

 分别代表种子图片文件名、开始像素点和结束像素点。

 

for(n = 0; n < threadCount; ++n)
	{
		paramArray[n].fileName = fileName;
		paramArray[n].start = createPerThread * n;
		paramArray[n].end = createPerThread * (n + 1);
		ret = pthread_create(&threads[n], &attr,  &do_create_image, &paramArray[n]);

		if(ret != 0)
		{
			perror("thread create");
			exit(EXIT_FAILURE);
		}
	}

	for(n = 0; n < threadCount; ++n)
	{
		ret = pthread_join(threads[n], NULL);
		if(ret != 0)
		{
			perror("thread join");
			exit(EXIT_FAILURE);
		}
	}

 是用pthread_create和pthread_join进行线程的创建和等待结束,是用多线程的方式大大增加了图片创建的速度,采用O2优化程度编译的代码,可以在13分钟创建1万张图片。

    最后,还是用了getopt函数来获得从命令行传入的参数。while((ret = getopt(argc, argv, "s:t:f:")) != -1)

while((ret = getopt(argc, argv, "s:t:f:")) != -1)	
{
		switch(ret)
		{
			case 's':
				totalCount = atoi(optarg);
				break;
			case 't':
				threadCount = atoi(optarg);
				break;
			case 'f':
				strncpy(fileName, optarg, 256);
				break;
			default:
				fprintf(stderr, "usage: %s [-s SUM] [-t THREAD_COUNT] [-f SEED_FILE]\n", argv[0]);
				exit(EXIT_FAILURE);
		}
	}

    因为这个小程序使用了gd库、pthread库,因此在编译的时候,需要连接着两个库。

CC = gcc
FLAGS = -O2
LIBS = -lpthread -lgd

EXE = jpg

all: $(EXE)

jpg: jpg_creator.c
	$(CC) $(FLAGS) -o $@ $? $(LIBS)

clean:
	rm $(EXE)
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics