view resize-gd.c @ 4:aa24986b8969

replaces simple Makefile with a good one
author meillo@marmaro.de
date Sat, 14 Jun 2008 12:00:23 +0200
parents 35a50e57b6f5
children 8e2804fe30bc
line wrap: on
line source

/*
 * compile with: gcc -lgd -lpng -lz -ljpeg  -lm resize-gd.c
 * build-depends: libgd2-noxpm-dev | libgd2-dev
 * depends: libgd2-noxpm | libgd2-xpm
 *
 *
 *
 * http://www.libgd.org/ImageCreation
 * http://cpan.uwinnipeg.ca/htdocs/Image-Resize/Image/Resize.pm.html
 * http://netpbm.sourceforge.net/
 *
 */

#include <stdio.h>
#include <stdlib.h>  /* for atoi() */
#include <string.h>
#include <ctype.h>
#include "gd.h" /* Bring in the gd library functions */


enum {
	Png,
	Jpg
};

struct size {
	int w;
	int h;
};


void
usage() {
	puts("\
usage: resize-gd <size> <imagefiles> [...]\n\
         (keeps aspect ratio, does not enlarge images)\n\
       resize-gd <width>x<height> <imagefiles> [...]\n\
         (resizes to that size, enlarges if needed)\n\
");
}


struct size
calcsize(struct size opt, struct size img, int enlarge) {
	struct size result;

	if (opt.h <= 0) {
		/* keep aspect ratio */
		if (!enlarge && opt.w > img.w && opt.w > img.h) {
			opt.w = (img.w > img.h) ? img.w : img.h;
		}
		if (img.w > img.h) {
			result.w = opt.w;
			result.h = opt.w * (1.0 * img.h / img.w);
		} else {
			result.h = opt.w;
			result.w = opt.w * (1.0 * img.w / img.h);
		}
	} else {
		result = opt;
	}
	return result;
}


int
validsize(char* sp) {
	while (isdigit(*sp)) {
		sp++;
	}
	if (*sp == 'x' && isdigit(*(sp+1))) {
		sp++;
		while (isdigit(*sp)) {
			sp++;
		}
	}
	if (*sp != '\0') {
		return 0;
	}
	return 1;
}


int
main(int argc, char* argv[]) {
	int i;
	int type;
	gdImagePtr im_in;
	gdImagePtr im_out;
	FILE* in;
	FILE* out;
	char* c;
	struct size sizeopt, sizeimg, sizedest;

	if (argc < 3) {
		usage();
		exit(1);
	}

	if (!validsize(argv[1])) {
		fprintf(stderr, "Invalid form of size. Has to be <size> or <width>x<height>.\n");
		usage();
		exit(3);
	}

	/* parse width and height */
	sizeopt.w = atoi(argv[1]);
	c = strstr(argv[1], "x");
	if (c && c[1] != '\0') {
		sizeopt.h = atoi(c + 1);
	} else {
		sizeopt.h = -1;  /* keep aspect ratio */
	}


	/* process images */
	for (i = 2; i < argc; i++) {
		printf("processing file '%s'\n", argv[i]);

		if (strcmp(argv[i]+strlen(argv[i])-4, ".png") == 0) {
			type = Png;
		} else if (strcmp(argv[i]+strlen(argv[i])-4, ".jpg") == 0) {
			type = Jpg;
		} else {
			fprintf(stderr, "'%s' has unknown filetype. Filename must end with (lowercase) '.png' or '.jpg'.\n", argv[i]);
			continue;
		}
		/* load image */
		in = fopen(argv[i], "rb");

		if (type == Png) {
			im_in = gdImageCreateFromPng(in);
		} else if (type == Jpg) {
			im_in = gdImageCreateFromJpeg(in);
		}
		/*
		if ((im_in = gdImageCreateFromPng(in)) != NULL) {
			type = Png;
		} else if ((im_in = gdImageCreateFromJpeg(in)) != NULL) {
			type = Jpg;
		} else {
			fprintf(stderr, "'%s' has unknown filetype. Filename must end with (lowercase) '.png' or '.jpg'.\n", argv[i]);
			continue;
		}
		*/

		fclose(in);

		/* calculate target size */
		sizeimg.w = im_in->sx;
		sizeimg.h = im_in->sy;
		sizedest = calcsize(sizeopt, sizeimg, 0);

		/* copy-resize the image */
		im_out = gdImageCreateTrueColor(sizedest.w, sizedest.h);
		gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0, im_out->sx, im_out->sy, im_in->sx, im_in->sy);

		/* write image */
		out = fopen(argv[i], "wb");
		if (type == Png) {
			gdImagePng(im_out, out);
		} else if (type == Jpg) {
			gdImageJpeg(im_out, out, -1);
		}
		fclose(out);

		gdImageDestroy(im_in);
		gdImageDestroy(im_out);
	}

	return 0;
}