diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2013-04-07 18:11:42 +0200 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2013-04-07 18:11:42 +0200 |
| commit | ced9539fef270fe133cb0ad6fc04c30bd5fa2dfe (patch) | |
| tree | 91e432faf1482e7adedcd0ea6e6942861325d7dc | |
| parent | d912f084ffbcae0ca4b8fdfb355d6bbd6a6d3506 (diff) | |
| download | cataract-ced9539fef270fe133cb0ad6fc04c30bd5fa2dfe.tar.xz | |
Add ability to specify thumbnail square crop hint
In simple crop square mode it's sometimes viable to specify position
of the square. This is vastly useful for portrait pictures so that you
don't crop the head off the body.
| -rw-r--r-- | sample/src/CIAF_1/index.xml | 9 | ||||
| -rw-r--r-- | src/generators.c | 15 | ||||
| -rw-r--r-- | src/items.c | 49 | ||||
| -rw-r--r-- | src/items.h | 13 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 25 | ||||
| -rw-r--r-- | src/jpeg-utils.h | 7 |
6 files changed, 100 insertions, 18 deletions
diff --git a/sample/src/CIAF_1/index.xml b/sample/src/CIAF_1/index.xml index 5d9ad5a..ed9e150 100644 --- a/sample/src/CIAF_1/index.xml +++ b/sample/src/CIAF_1/index.xml @@ -26,7 +26,10 @@ <author>John Doe Jr.</author> <description>CIAF - Czech International Air Fest 2007</description> <keywords>ciaf,aircraft,military,exhibition</keywords> - </meta> + </meta> + + <!-- global thumbnail crop hint for simple square mode --> + <thumbnail crop="top" /> </general> <items> @@ -38,12 +41,14 @@ <item src="img_6802.jpg" preview="preview/img_6802.jpg"> <title>Photo title</title> <title_description>This photo uses supplied preview image. Some people (me) can see the difference in sharpness.</title_description> + <thumbnail crop="center" /> </item> <item src="img_6802c.jpg" preview="preview/img_6802.jpg"> <nofullsize /> <title>Photo title</title> <title_description>This photo doesn't contain link to original image, but src parameter is specified.</title_description> + <thumbnail crop="bottom" /> </item> <separator><![CDATA[This is a separator inside a single album. We <span style="text-decoration: underline;">can</span> <small>have</small> <strong>CDATA</strong> entries here!]]></separator> @@ -114,6 +119,7 @@ <metadata> <external_exif src="exif/5l9a4978.exv" /> </metadata> + <thumbnail crop="left" /> </item> <item src="img_1453c.jpg"> @@ -132,6 +138,7 @@ <external_exif src="exif/5l9a4978.exv" /> <timezone shift="+02:15" /> </metadata> + <thumbnail crop="right" /> </item> </items> diff --git a/src/generators.c b/src/generators.c index 52ec1ac..2038424 100644 --- a/src/generators.c +++ b/src/generators.c @@ -170,6 +170,12 @@ metadata_apply_overrides (ExifData *exif_data, exif_data->external_exif_data = NULL; if (setup->write_supplied_exif && item->metadata_external_exif) exif_data->external_exif_data = g_build_filename (path_info->src_dir, item->metadata_external_exif, NULL); + + exif_data->squared_thumbnail_type = setup->squared_thumbnail_type; + + exif_data->thumbnail_crop_hint = item->thumbnail_crop_hint; + if (exif_data->thumbnail_crop_hint == CROP_HINT_UNDEFINED) + exif_data->thumbnail_crop_hint = items->thumbnail_crop_hint; } @@ -212,6 +218,9 @@ generate_image (TGallerySetup *setup, if (img_src == NULL || img_dst == NULL) continue; + exif_data = exif_data_new_empty (); + metadata_apply_overrides (exif_data, setup, path_info, items, item); + /* Do something when required */ res = res || needs_update (img_src, img_dst); if (! query_update) { @@ -251,7 +260,7 @@ generate_image (TGallerySetup *setup, quality = item->quality; /* Perform resize and strip */ - if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->squared_thumbnail_type, setup->autorotate)) + if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->autorotate, exif_data)) log_error ("generate_image: error resizing image %s\n", img_src); } else { log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, img_w, img_h); @@ -259,12 +268,10 @@ generate_image (TGallerySetup *setup, } } if (! is_thumbnail) { - exif_data = exif_data_new_empty (); - metadata_apply_overrides (exif_data, setup, path_info, items, item); modify_exif (img_dst, exif_data, setup->erase_exif_thumbnail, setup->strip_xmp); - exif_data_free (exif_data); } + exif_data_free (exif_data); g_free (img_src); g_free (img_dst); } diff --git a/src/items.c b/src/items.c index 85f0a26..31ab41f 100644 --- a/src/items.c +++ b/src/items.c @@ -85,6 +85,29 @@ parse_datetime_string (const gchar *str) return rt; } +static TCropHint +parse_thumbnail_crop_hint (const gchar *str) +{ + g_return_val_if_fail (str != NULL, CROP_HINT_UNDEFINED); + + if (g_ascii_strcasecmp (str, "center") == 0) + return CROP_HINT_CENTER; + else + if (g_ascii_strcasecmp (str, "left") == 0) + return CROP_HINT_LEFT; + else + if (g_ascii_strcasecmp (str, "right") == 0) + return CROP_HINT_RIGHT; + else + if (g_ascii_strcasecmp (str, "top") == 0) + return CROP_HINT_TOP; + else + if (g_ascii_strcasecmp (str, "bottom") == 0) + return CROP_HINT_BOTTOM; + else + return CROP_HINT_UNDEFINED; +} + /* * parse_album_xml: XML parser for gallery index.xml files @@ -161,6 +184,12 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) g_free (s); } + s = xml_file_get_node_attribute (xml, "/gallery/general/thumbnail", "crop"); + if (s != NULL) { + index->thumbnail_crop_hint = parse_thumbnail_crop_hint (s); + g_free (s); + } + index->nofullsize = xml_file_get_node_present (xml, "/gallery/general/nofullsize"); index->fullsize = xml_file_get_node_present (xml, "/gallery/general/fullsize"); @@ -306,6 +335,14 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) g_free (s2); } + s = g_strdup_printf ("/gallery/items/*[%d]/thumbnail", i + 1); + s2 = xml_file_get_node_attribute (xml, s, "crop"); + g_free (s); + if (s2 != NULL) { + item->thumbnail_crop_hint = parse_thumbnail_crop_hint (s2); + g_free (s2); + } + if (item->path || item->preview) { g_ptr_array_add (index->items, item); } else { @@ -422,15 +459,15 @@ free_album_data (TAlbum *album) * get_album_info: retrieve number of items and protected status in the specified album */ void -get_album_info (const gchar *filename, int *objects_count, gboolean *protected) +get_album_info (const gchar *filename, int *objects_count, gboolean *is_protected) { TXMLFile *xml; int count, hidden; if (objects_count) *objects_count = 0; - if (protected) - *protected = FALSE; + if (is_protected) + *is_protected = FALSE; xml = xml_parser_load (filename); if (xml == NULL) @@ -441,9 +478,9 @@ get_album_info (const gchar *filename, int *objects_count, gboolean *protected) if (objects_count) *objects_count = count - hidden; - if (protected) - *protected = xml_file_get_node_present (xml, "/gallery/general/auth/username") && - xml_file_get_node_present (xml, "/gallery/general/auth/password"); + if (is_protected) + *is_protected = xml_file_get_node_present (xml, "/gallery/general/auth/username") && + xml_file_get_node_present (xml, "/gallery/general/auth/password"); xml_parser_free (xml); } diff --git a/src/items.h b/src/items.h index 331f29e..b502e71 100644 --- a/src/items.h +++ b/src/items.h @@ -39,6 +39,15 @@ typedef enum { AUTH_TYPE_BASIC } TAuthType; +typedef enum { + CROP_HINT_UNDEFINED = 0, + CROP_HINT_CENTER, + CROP_HINT_LEFT, + CROP_HINT_RIGHT, + CROP_HINT_TOP, + CROP_HINT_BOTTOM +} TCropHint; + typedef struct { TGalleryType type; gchar *ID; @@ -66,6 +75,7 @@ typedef struct { TAuthType auth_type; int metadata_tz_shift; /* minutes */ time_t metadata_fake_datetime; + TCropHint thumbnail_crop_hint; } TAlbum; typedef struct { @@ -85,6 +95,7 @@ typedef struct { gchar *metadata_external_exif; int metadata_tz_shift; /* minutes */ time_t metadata_fake_datetime; + TCropHint thumbnail_crop_hint; } TIndexItem; typedef struct { @@ -115,7 +126,7 @@ void free_album_data (TAlbum *index); /* * get_album_info: retrieve number of items and protected status in the specified album */ -void get_album_info (const gchar *filename, int *objects_count, gboolean *protected); +void get_album_info (const gchar *filename, int *objects_count, gboolean *is_protected); /* * get_album_titles: retrieve title, description and first thumbnail from specified album diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp index d7382c8..be95ec9 100644 --- a/src/jpeg-utils.cpp +++ b/src/jpeg-utils.cpp @@ -432,8 +432,8 @@ resize_image (const gchar *src, const gchar *dst, unsigned long size_x, unsigned long size_y, int quality, gboolean thumbnail, - ThumbnailSquareType squared_thumbnail_type, - gboolean autorotate) + gboolean autorotate, + ExifData *exif) { MagickWand *magick_wand; ExceptionType severity; @@ -460,13 +460,30 @@ resize_image (const gchar *src, const gchar *dst, { /* Process thumbnail if required */ if (thumbnail) { - switch (squared_thumbnail_type) { + switch (exif->squared_thumbnail_type) { case THUMBNAIL_SQUARE_TYPE_SIMPLE: w = MagickGetImageWidth (magick_wand); h = MagickGetImageHeight (magick_wand); amount = MAX (w, h) * SQUARED_SIMPLE_SHAVE_AMOUNT / 100; amount = MIN (w - 2*amount, h - 2*amount); - MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, (h - amount) / 2); + switch (exif->thumbnail_crop_hint) { + case CROP_HINT_UNDEFINED: + case CROP_HINT_CENTER: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, (h - amount) / 2); + break; + case CROP_HINT_LEFT: + MagickCropImage (magick_wand, amount, amount, 0, (h - amount) / 2); + break; + case CROP_HINT_RIGHT: + MagickCropImage (magick_wand, amount, amount, w - amount, (h - amount) / 2); + break; + case CROP_HINT_TOP: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, 0); + break; + case CROP_HINT_BOTTOM: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, h - amount); + break; + } break; default: break; diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h index 0e3cd1f..f8c9b6d 100644 --- a/src/jpeg-utils.h +++ b/src/jpeg-utils.h @@ -20,6 +20,7 @@ #include <glib.h> #include "setup.h" +#include "items.h" G_BEGIN_DECLS @@ -54,6 +55,8 @@ typedef struct { int timezone_shift; time_t fake_datetime; gchar *external_exif_data; + ThumbnailSquareType squared_thumbnail_type; + TCropHint thumbnail_crop_hint; } ExifData; @@ -87,8 +90,8 @@ gboolean resize_image (const gchar *src, const gchar *dst, unsigned long size_x, unsigned long size_y, int quality, gboolean thumbnail, - ThumbnailSquareType squared_thumbnail_type, - gboolean autorotate); + gboolean autorotate, + ExifData *exif); /* * get_image_sizes: retrieve image dimensions |
