diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2015-01-04 23:01:42 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2015-01-04 23:01:42 +0100 |
| commit | 248a9af6ad668b6f09f79dda548721756fe11d79 (patch) | |
| tree | 6ace053a06d55935e6ff2ba1bf571ab5d6fa7c61 | |
| parent | cd4658f7154fbfa58c09c101b9753ef85a62620d (diff) | |
| download | cataract-248a9af6ad668b6f09f79dda548721756fe11d79.tar.xz | |
Introduce new "fixed" thumbnail crop mode
This mode retains given aspect ratio and crops the area from inside of the
source image.
| -rw-r--r-- | src/generators.c | 19 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 40 | ||||
| -rw-r--r-- | src/jpeg-utils.h | 4 | ||||
| -rw-r--r-- | src/setup.c | 13 | ||||
| -rw-r--r-- | src/setup.h | 9 | ||||
| -rw-r--r-- | templates/default.xml | 12 |
6 files changed, 74 insertions, 23 deletions
diff --git a/src/generators.c b/src/generators.c index 2e8cca6..f627839 100644 --- a/src/generators.c +++ b/src/generators.c @@ -300,7 +300,7 @@ metadata_apply_overrides (ExifData *exif_data, if (setup->write_supplied_exif && item->metadata_external_exif) exif_data->external_exif_data = g_path_is_absolute (item->metadata_external_exif) ? g_strdup (item->metadata_external_exif) : g_build_filename (path_info->src_dir, item->metadata_external_exif, NULL); - exif_data->squared_thumbnail = image_size->is_thumbnail && image_size->squared_thumb; + exif_data->thumbnail_crop_style = image_size->is_thumbnail ? image_size->thumb_crop_style : CROP_STYLE_NORMAL; exif_data->thumbnail_crop_hint = get_prop_int (items, item, PROP_THUMB_CROP_HINT, CROP_HINT_UNDEFINED); } @@ -403,8 +403,19 @@ generate_image (TGallerySetup *setup, if (img_w > 0 && img_h > 0) { stats_images_inc (); - if (image_size->is_thumbnail && image_size->squared_thumb) - img_w = img_h = image_size->square_size; + if (image_size->is_thumbnail && image_size->thumb_crop_style != CROP_STYLE_NORMAL) { + switch (image_size->thumb_crop_style) { + case CROP_STYLE_SQUARED: + img_w = img_h = image_size->square_size; + break; + case CROP_STYLE_FIXED: + img_w = image_size->crop_width; + img_h = image_size->crop_height; + break; + default: + g_assert_not_reached (); + } + } else { /* Only the "preview" size is affected by deprecated item and album overrides */ if (is_preview) { @@ -795,7 +806,7 @@ process_img_item (TGallerySetup *setup, if (s2 != NULL) get_image_sizes (s2, &img_thumb_w, &img_thumb_h, setup->autorotate); - if (thumb_image_size->squared_thumb || img_thumb_w == img_thumb_h) + if (img_thumb_w == img_thumb_h) replace_table_add_key (replace_table, "THUMB_ORIENTATION", "squared"); else replace_table_add_key (replace_table, "THUMB_ORIENTATION", (img_thumb_h > img_thumb_w) ? "portrait" : "landscape"); diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp index a552e69..e714778 100644 --- a/src/jpeg-utils.cpp +++ b/src/jpeg-utils.cpp @@ -458,9 +458,9 @@ resize_image (const gchar *src, const gchar *dst, { MagickWand *magick_wand; ExceptionType severity; - unsigned long w; - unsigned long h; - unsigned long amount; + unsigned long w, h; + unsigned long new_w, new_h; + double source_aspect, target_aspect; gchar *description; /* Read an image. */ @@ -481,27 +481,45 @@ resize_image (const gchar *src, const gchar *dst, { /* Process thumbnail if required */ if (thumbnail) { - if (exif->squared_thumbnail) { + if (exif->thumbnail_crop_style != CROP_STYLE_NORMAL) { 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); + new_w = w; + new_h = h; + if (exif->thumbnail_crop_style == CROP_STYLE_SQUARED) { + new_w = MAX (w, h) * CROP_SIMPLE_SHAVE_AMOUNT / 100; + new_w = MIN (w - 2*new_w, h - 2*new_w); + new_h = new_w; + } + if (exif->thumbnail_crop_style == CROP_STYLE_FIXED) { + source_aspect = (double) w / (double) h; + target_aspect = (double) size_x / (double) size_y; + if (target_aspect >= source_aspect) { + new_w = w; + new_h = (int) ((double) w / target_aspect); + } else { + new_w = (int) ((double) h * target_aspect); + new_h = h; + } + new_w = (int) ((double) new_w * (double) (100 - CROP_SIMPLE_SHAVE_AMOUNT) / 100); + new_h = (int) ((double) new_h * (double) (100 - CROP_SIMPLE_SHAVE_AMOUNT) / 100); + } switch (exif->thumbnail_crop_hint) { case CROP_HINT_UNDEFINED: case CROP_HINT_CENTER: - MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, (h - amount) / 2); + MagickCropImage (magick_wand, new_w, new_h, (w - new_w) / 2, (h - new_h) / 2); break; case CROP_HINT_LEFT: - MagickCropImage (magick_wand, amount, amount, 0, (h - amount) / 2); + MagickCropImage (magick_wand, new_w, new_h, 0, (h - new_h) / 2); break; case CROP_HINT_RIGHT: - MagickCropImage (magick_wand, amount, amount, w - amount, (h - amount) / 2); + MagickCropImage (magick_wand, new_w, new_h, w - new_w, (h - new_h) / 2); break; case CROP_HINT_TOP: - MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, 0); + MagickCropImage (magick_wand, new_w, new_h, (w - new_w) / 2, 0); break; case CROP_HINT_BOTTOM: - MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, h - amount); + MagickCropImage (magick_wand, new_w, new_h, (w - new_w) / 2, h - new_h); break; } } diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h index 3700d66..9e4c729 100644 --- a/src/jpeg-utils.h +++ b/src/jpeg-utils.h @@ -25,7 +25,7 @@ G_BEGIN_DECLS -#define SQUARED_SIMPLE_SHAVE_AMOUNT 0 /* percent */ +#define CROP_SIMPLE_SHAVE_AMOUNT 0 /* percent */ /* EXIF data known keys */ #define EXIF_APERTURE "Exif.Photo.FNumber" @@ -57,7 +57,7 @@ typedef struct { double override_aperture; double override_focal_length; gchar *external_exif_data; - gboolean squared_thumbnail; + TCropStyle thumbnail_crop_style; TCropHint thumbnail_crop_hint; } ExifData; diff --git a/src/setup.c b/src/setup.c index d945021..5cfc255 100644 --- a/src/setup.c +++ b/src/setup.c @@ -193,10 +193,14 @@ parse_design_setup_xml (const gchar *filename) if (s2 && g_ascii_strcasecmp (s2, "thumbnail") == 0) image_size->is_thumbnail = TRUE; g_free (s2); + image_size->thumb_crop_style = CROP_STYLE_NORMAL; if (image_size->is_thumbnail) { s2 = xml_file_get_node_attribute (xml, s, "style"); if (s2 && g_ascii_strcasecmp (s2, "squared") == 0) - image_size->squared_thumb = TRUE; + image_size->thumb_crop_style = CROP_STYLE_SQUARED; + else + if (s2 && g_ascii_strcasecmp (s2, "fixed") == 0) + image_size->thumb_crop_style = CROP_STYLE_FIXED; g_free (s2); } g_free (s); @@ -219,6 +223,11 @@ parse_design_setup_xml (const gchar *filename) image_size->square_size = xml_file_get_node_attribute_long_with_default (xml, s, "size", 0); g_free (s); + s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/crop", i + 1); + image_size->crop_width = xml_file_get_node_attribute_long_with_default (xml, s, "w", 0); + image_size->crop_height = xml_file_get_node_attribute_long_with_default (xml, s, "h", 0); + g_free (s); + s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/quality", i + 1); image_size->quality = xml_file_get_node_attribute_long_with_default (xml, s, "value", -1); g_free (s); @@ -347,7 +356,7 @@ makeup_legacy_design (const gchar *filename) image_size->quality = xml_file_get_node_attribute_long_with_default (xml, s, "quality", -1); image_size->no_resize = (i != 0); image_size->is_thumbnail = (i == 0); - image_size->squared_thumb = (i == 0) && squared_thumbs; + image_size->thumb_crop_style = ((i == 0) && squared_thumbs) ? CROP_STYLE_SQUARED : CROP_STYLE_NORMAL; g_free (s); design->image_sizes = g_list_append (design->image_sizes, image_size); } diff --git a/src/setup.h b/src/setup.h index 4678423..f49eb9a 100644 --- a/src/setup.h +++ b/src/setup.h @@ -86,6 +86,11 @@ typedef struct { gchar *footer; } TGallerySetup; +typedef enum { + CROP_STYLE_NORMAL = 0, + CROP_STYLE_SQUARED, + CROP_STYLE_FIXED +} TCropStyle; typedef struct { gchar *name; @@ -95,9 +100,11 @@ typedef struct { int portrait_width; int portrait_height; int square_size; + int crop_width; + int crop_height; int quality; gboolean no_resize; - gboolean squared_thumb; + TCropStyle thumb_crop_style; } TImageSize; typedef struct { diff --git a/templates/default.xml b/templates/default.xml index c903a4b..3948538 100644 --- a/templates/default.xml +++ b/templates/default.xml @@ -46,13 +46,19 @@ <!-- Thumbnail section is mandatory. --> <!-- Corresponds with optional <item thumbnail> tag in album source file. Note that thumbnail images are always resized even for custom supplied files. --> - <!-- The "type" attribute has to be set to "thumbnail" to be treated as such. - An optional "style" attribute set to "squared" indicates the need of squared - thumbnails as opposed to original aspect ratio. --> + <!-- The "type" attribute has to be set to "thumbnail" to be treated as such. --> + <!-- An optional "style" attribute affects cropping: + * normal - image is resized to fit the dimension limits, maintaining + aspect ratio without any crop (default) + * squared - image is cropped to a squared size and resized to fit + * fixed - image is cropped to a specified dimension and cropped to + fit the specified aspect ratio + An optional album item <thumbnail crop> tags may affect crop area. --> <size name="thumbnail" type="thumbnail" style="normal"> <landscape w="180" h="120" /> <portrait w="120" h="180" /> <square size="180" /> + <crop w="180" h="120" /> <!-- valid only for the "fixed" crop style --> <quality value="80" /> </size> |
