int main( int argc, char **argv ) { FILE *fp; gdImagePtr original, cropped,resized; if( argc != 3 ) { printf( "usage: %s in-jpeg out-jpeg\n", argv[0] ); exit( 1 ); } if( !(fp = fopen( argv[1], "r" )) ) { printf( "unable to open \"%s\"\n", argv[1] ); exit( 1 ); } if( !(original = gdImageCreateFromJpeg( fp )) ) { printf( "unable to load \"%s\"\n", argv[1] ); exit( 1 ); } fclose( fp ); gdRect crop; crop.x = 100; crop.y = 100; crop.width = original->sx - 200; crop.height = original->sy - 200; cropped = gdImageCrop(original, &crop); gdImageDestroy( original ); original = 0; if( !(cropped) ) { printf( "unable to crop image\n" ); exit( 1 ); } resized = gdImageScale(cropped, crop.width * 0.9, crop.height * 0.9); gdImageDestroy( cropped ); cropped = 0; if( !(resized) ) { printf( "unable to resize image\n" ); exit( 1 ); } //gdImageSharpen is extremely slow //gdImageSharpen( resized, 75 ); if( !(fp = fopen( argv[2], "w" )) ) { printf( "unable to open \"%s\"\n", argv[2] ); exit( 1 ); } gdImageJpeg( resized, fp, -1 ); fclose( fp ); gdImageDestroy( resized ); return( 0 ); }
/** * Function: gdImageCropAuto * * Crop an image automatically * * This function detects the cropping area according to the given _mode_. * * Parameters: * im - The image. * mode - The cropping mode, see <gdCropMode>. * * Returns: * The newly created cropped image, or NULL on failure. * * See also: * - <gdImageCrop> * - <gdImageCropThreshold> */ BGD_DECLARE(gdImagePtr) gdImageCropAuto(gdImagePtr im, const unsigned int mode) { const int width = gdImageSX(im); const int height = gdImageSY(im); int x,y; int color, match; gdRect crop; crop.x = 0; crop.y = 0; crop.width = 0; crop.height = 0; switch (mode) { case GD_CROP_TRANSPARENT: color = gdImageGetTransparent(im); break; case GD_CROP_BLACK: color = gdImageColorClosestAlpha(im, 0, 0, 0, 0); break; case GD_CROP_WHITE: color = gdImageColorClosestAlpha(im, 255, 255, 255, 0); break; case GD_CROP_SIDES: gdGuessBackgroundColorFromCorners(im, &color); break; case GD_CROP_DEFAULT: default: color = gdImageGetTransparent(im); break; } /* TODO: Add gdImageGetRowPtr and works with ptr at the row level * for the true color and palette images * new formats will simply work with ptr */ match = 1; for (y = 0; match && y < height; y++) { for (x = 0; match && x < width; x++) { match = (color == gdImageGetPixel(im, x,y)); } } /* Whole image would be cropped > bye */ if (match) { return NULL; } crop.y = y - 1; match = 1; for (y = height - 1; match && y >= 0; y--) { for (x = 0; match && x < width; x++) { match = (color == gdImageGetPixel(im, x,y)); } } crop.height = y - crop.y + 2; match = 1; for (x = 0; match && x < width; x++) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (color == gdImageGetPixel(im, x,y)); } } crop.x = x - 1; match = 1; for (x = width - 1; match && x >= 0; x--) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (color == gdImageGetPixel(im, x,y)); } } crop.width = x - crop.x + 2; return gdImageCrop(im, &crop); }
/** * Function: gdImageCropThreshold * * Crop an image using a given color * * The _threshold_ defines the tolerance to be used while comparing the image * color and the color to crop. The method used to calculate the color * difference is based on the color distance in the RGB(A) cube. * * Parameters: * im - The image. * color - The crop color. * threshold - The crop threshold. * * Returns: * The newly created cropped image, or NULL on failure. * * See also: * - <gdImageCrop> * - <gdImageCropAuto> */ BGD_DECLARE(gdImagePtr) gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold) { const int width = gdImageSX(im); const int height = gdImageSY(im); int x,y; int match; gdRect crop; crop.x = 0; crop.y = 0; crop.width = 0; crop.height = 0; /* Pierre: crop everything sounds bad */ if (threshold > 100.0) { return NULL; } if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) { return NULL; } /* TODO: Add gdImageGetRowPtr and works with ptr at the row level * for the true color and palette images * new formats will simply work with ptr */ match = 1; for (y = 0; match && y < height; y++) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } /* Whole image would be cropped > bye */ if (match) { return NULL; } crop.y = y - 1; match = 1; for (y = height - 1; match && y >= 0; y--) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0; } } crop.height = y - crop.y + 2; match = 1; for (x = 0; match && x < width; x++) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.x = x - 1; match = 1; for (x = width - 1; match && x >= 0; x--) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.width = x - crop.x + 2; return gdImageCrop(im, &crop); }
/** * Function: gdImageThresholdCrop * Crop an image using a given color. The threshold argument defines * the tolerance to be used while comparing the image color and the * color to crop. The method used to calculate the color difference * is based on the color distance in the RGB(a) cube. * * * Parameters: * im - Source image * color - color to crop * threshold - tolerance (0..100) * * Returns: * <gdImagePtr> on success or NULL * * See also: * <gdCropMode>, <gdImageAutoCrop> or <gdImageCrop> */ gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold) { const int width = gdImageSX(im); const int height = gdImageSY(im); int x,y; int match; gdRect crop; crop.x = 0; crop.y = 0; crop.width = 0; crop.height = 0; /* Pierre: crop everything sounds bad */ if (threshold > 1.0) { return NULL; } /* TODO: Add gdImageGetRowPtr and works with ptr at the row level * for the true color and palette images * new formats will simply work with ptr */ match = 1; for (y = 0; match && y < height; y++) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } /* Pierre * Nothing to do > bye * Duplicate the image? */ if (y == height - 1) { return NULL; } crop.y = y -1; match = 1; for (y = height - 1; match && y >= 0; y--) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0; } } if (y == 0) { crop.height = height - crop.y + 1; } else { crop.height = y - crop.y + 2; } match = 1; for (x = 0; match && x < width; x++) { for (y = 0; match && y < crop.y + crop.height - 1; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.x = x - 1; match = 1; for (x = width - 1; match && x >= 0; x--) { for (y = 0; match && y < crop.y + crop.height - 1; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.width = x - crop.x + 2; return gdImageCrop(im, &crop); }
/** * Function: gdImageAutoCrop * Automatic croping of the src image using the given mode * (see <gdCropMode>) * * * Parameters: * im - Source image * mode - crop mode * * Returns: * <gdImagePtr> on success or NULL * * See also: * <gdCropMode> */ gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode) { const int width = gdImageSX(im); const int height = gdImageSY(im); int x,y; int color, corners, match; gdRect crop; crop.x = 0; crop.y = 0; crop.width = 0; crop.height = 0; switch (mode) { case GD_CROP_TRANSPARENT: color = gdImageGetTransparent(im); break; case GD_CROP_BLACK: color = gdImageColorClosestAlpha(im, 0, 0, 0, 0); break; case GD_CROP_WHITE: color = gdImageColorClosestAlpha(im, 255, 255, 255, 0); break; case GD_CROP_SIDES: corners = gdGuessBackgroundColorFromCorners(im, &color); break; case GD_CROP_DEFAULT: default: color = gdImageGetTransparent(im); if (color == -1) { corners = gdGuessBackgroundColorFromCorners(im, &color); } break; } /* TODO: Add gdImageGetRowPtr and works with ptr at the row level * for the true color and palette images * new formats will simply work with ptr */ match = 1; for (y = 0; match && y < height; y++) { for (x = 0; match && x < width; x++) { int c2 = gdImageGetPixel(im, x, y); match = (color == c2); } } /* Nothing to do > bye * Duplicate the image? */ if (y == height - 1) { return NULL; } crop.y = y -1; match = 1; for (y = height - 1; match && y >= 0; y--) { for (x = 0; match && x < width; x++) { match = (color == gdImageGetPixel(im, x,y)); } } if (y == 0) { crop.height = height - crop.y + 1; } else { crop.height = y - crop.y + 2; } match = 1; for (x = 0; match && x < width; x++) { for (y = 0; match && y < crop.y + crop.height - 1; y++) { match = (color == gdImageGetPixel(im, x,y)); } } crop.x = x - 1; match = 1; for (x = width - 1; match && x >= 0; x--) { for (y = 0; match && y < crop.y + crop.height - 1; y++) { match = (color == gdImageGetPixel(im, x,y)); } } crop.width = x - crop.x + 2; if (crop.x <= 0 || crop.y <= 0 || crop.width <= 0 || crop.height <= 0) { return NULL; } return gdImageCrop(im, &crop); }