/* seamless.c - Seam Carving to Resize Images Source: http://inamidst.com/code/seamless.c Written by Arthur B., http://slashdot.org/~Arthur+B./ Cf. http://slashdot.org/comments.pl?sid=279819&cid=20359241 Modified by Sean B. Palmer, http://inamidst.com/sbp/ Contributions of help from: * Adam Wendt, http://blog.thelsdj.com/ * Björn Höhrmann, http://bjoern.hoehrmann.de/ * Kevin Reid, http://homepage.mac.com/kpreid/ Requirements: http://www.libgd.org/ Usage: ./seamless [ "v" ] e.g. ./seamless in.png out.jpg 150 v -> Take 150 vertical seams from in.png gcc -O3 -o seamless -lgd -L/opt/local/lib -I/opt/local/include seamless.c Caveat: segfaults on very large images; dunno why */ #define min(a,b) ((a)<(b)?(a):(b)) #include #include #include #include #include #include int greyscale(int *grey, gdImagePtr img, int sx, int sy) { int i, j; for (i=1; i [ v ]\n"); printf(" e.g. ./seamless in.png out.jpg 150 v\n"); printf(" -> Take 150 vertical seams from in.png\n"); exit(1); } int main(int argc, char *argv[]) { int vertical; if (argc == 4) vertical = 0; else if (argc == 5) vertical = 1; else doc(); char *fn = argv[1]; gdImagePtr eimg; FILE *f = fopen(fn, "rb"); if (strcasecmp(strrchr(fn, '.'), ".jpg") == 0) eimg = gdImageCreateFromJpeg(f); else eimg = gdImageCreateFromPng(f); fclose(f); int sx = gdImageSX(eimg); int sy = gdImageSY(eimg); gdImagePtr img; if (vertical == 0) { img = gdImageCreateTrueColor(sy, sx); gdImageCopyRotated(img, eimg, ((float)sy)/2,((float)sx)/2,0,0,sx,sy,90); gdImageDestroy(eimg); sx = gdImageSX(img); sy = gdImageSY(img); } else img = eimg; int* imageGradient = malloc(sx * sy * sizeof(*imageGradient)); int* grey = malloc(sx * sy * sizeof(*grey)); greyscale(grey, img, sx, sy); gradient(imageGradient, grey, sx, sy); int seams, i, j; int maxseams = atoi(argv[3]); for (seams=0; seams=0; --i) { weight[i][0] = min(weight[i+1][0], weight[i+1][1]) + imageGradient[i * sy + 0]; weight[i][sy-1] = min(weight[i+1][sy-1], weight[i+1][sy-2]) + imageGradient[i * sy + (sy-1)]; for (j=1; j=0.5)?(bestj[i-1]+1):(bestj[i-1]-1); else if (weight[i][bestj[i-1]-1] <= weight[i][bestj[i-1]] && weight[i][bestj[i-1]-1] <= weight[i][bestj[i-1]+1]) bestj[i] = bestj[i-1]-1; else bestj[i] = bestj[i-1]+1; } gdImagePtr imgout = gdImageCreateTrueColor(sx, sy-1); int jj; for(i=0; i