diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-04-20 20:57:57 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-04-21 19:37:06 +0300 |
commit | 50bfc4bfa0eabb68fcb5b5e82f80281fbaddcfeb (patch) | |
tree | 5ee5ecd548454b8464efb35ded40a22792d17e36 /source | |
parent | f9972fa53eaab4d1e8fd7b435f6f65c1ac5501e1 (diff) |
Metadata display support - patch by Julian and me.
Basically, blender adds a few metadata fields to images when
we render an image. Those metadata can now be viewed in the
image editor.
Also, made sure metadata are available when we write imbufs
to disc with "Save As". There may be more cases here that need
fixing, but this means that loading an image with metadata
will now properly preserve them in blender.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 1 | ||||
-rw-r--r-- | source/blender/editors/include/ED_util.h | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 197 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_draw.c | 25 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 7 | ||||
-rw-r--r-- | source/blender/editors/space_image/space_image.c | 2 | ||||
-rw-r--r-- | source/blender/editors/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 15 | ||||
-rw-r--r-- | source/blender/imbuf/intern/IMB_metadata.h | 10 | ||||
-rw-r--r-- | source/blender/imbuf/intern/metadata.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 5 |
12 files changed, 252 insertions, 21 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 90b0b3510bc..b7c261cad6c 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -66,6 +66,7 @@ void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float fill_color[4]); +void ED_region_image_metadata_draw(struct ARegion *ar, struct ImBuf *ibuf, float zoomx, float zoomy); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); float ED_region_blend_factor(struct ARegion *ar); void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect); diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 9556c601d1f..96d7828ffe9 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -42,6 +42,8 @@ void ED_editors_exit(struct bContext *C); bool ED_editors_flush_edits(const struct bContext *C, bool for_render); +void ED_draw_ibuf_meta_data(const bContext *C, struct ImBuf *ibuf); + /* ************** Undo ************************ */ /* undo.c */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index d786c0cfc36..1c87d959dc4 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -61,6 +61,9 @@ #include "BIF_glutil.h" #include "BLF_api.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + #include "UI_interface.h" #include "UI_interface_icons.h" #include "UI_resources.h" @@ -2027,6 +2030,200 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_co glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); } +#define MAX_METADATA_STR 1024 + +const char *meta_data_list[] = +{ + "File", + "Strip", + "Note", + "Date", + "RenderTime", + "Marker", + "Time", + "Frame", + "Camera", + "Scene" +}; + +BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index) +{ + return (IMB_metadata_get_field(ibuf, meta_data_list[index], r_str, MAX_METADATA_STR) && r_str[0]); +} + +static void metadata_draw_lines(ImBuf *ibuf, rcti rect, int fontid, const bool is_top) +{ + char temp_str[MAX_METADATA_STR]; + int line_width, line_height; + int ofs_y = 0; + short line_index; + short i; + + for (line_index = 0; line_index < 4 && is_top == true; line_index++) { + /* first line */ + if (line_index == 0) { + int len; + bool do_newline = false; + float height = 0.0; + BLI_snprintf(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]); + len = strlen(temp_str); + if (metadata_is_valid(ibuf, temp_str + len, 0)) { + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit), + rect.ymax - (1.5f * U.widget_unit - UI_UNIT_Y), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + height = BLF_height(fontid, temp_str, strlen(temp_str)); + } + + BLI_snprintf(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]); + len = strlen(temp_str); + if (metadata_is_valid(ibuf, temp_str + len, 1)) { + len = strlen(temp_str); + line_width = BLF_width(fontid, temp_str, len); + BLF_position(fontid, rect.xmax - line_width - (0.2f * U.widget_unit), + rect.ymax - (1.5f * U.widget_unit - UI_UNIT_Y), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + height = max_ff(BLF_height(fontid, temp_str, len), height); + } + + if (do_newline) + ofs_y += (height + (0.2f * U.widget_unit)); + } + else if (line_index == 1) { + if (metadata_is_valid(ibuf, temp_str, line_index + 1)) { + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit), + rect.ymax - (1.5f * U.widget_unit - UI_UNIT_Y) - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += (BLF_height(fontid, temp_str, strlen(temp_str)) + (0.2f * U.widget_unit)); + } + } + else { + if (metadata_is_valid(ibuf, temp_str, line_index + 1)) { + BLF_position(fontid, rect.xmax + (0.2f * U.widget_unit), + rect.ymax - (1.5f * U.widget_unit - UI_UNIT_Y) - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += (BLF_height(fontid, temp_str, strlen(temp_str)) + (0.2f * U.widget_unit)); + } + } + } + + if (is_top == false) { + int ofs_x = 0; + for (i = 5; i < 10; i++) { + if (metadata_is_valid(ibuf, temp_str, i)) { + line_height = BLF_height(fontid, temp_str, strlen(temp_str)); + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit) + ofs_x, + rect.ymin - line_height + (1.5f * U.widget_unit), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + + ofs_x += BLF_width(fontid, temp_str, strlen(temp_str)) + UI_UNIT_X; + } + } + } +} + +static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top) +{ + char str[MAX_METADATA_STR]; + float height = 0; + short i; + + if (is_top) { + for (i = 0; i < 5 ; i++) { + if (metadata_is_valid(ibuf, str, i)) { + height += BLF_height(fontid, str, strlen(str)); + } + } + } + else { + for (i = 5; i < 10; i++) { + if (metadata_is_valid(ibuf, str, i)) { + height += BLF_height(fontid, str, strlen(str)); + } + } + } + + if (height) { + return (height + (0.2f * U.widget_unit)); + } + + return 0; +} + +#undef MAX_METADATA_STR + +void ED_region_image_metadata_draw(ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy) +{ + uiStyle *style = UI_style_get_dpi(); + int fontid = style->widget.uifont_id; + float box_y; + rcti rect; + int x, y; + + if (!ibuf->metadata) + return; + + /* find window pixel coordinates of origin */ + UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); + + glPushMatrix(); + + /* offset and zoom using ogl */ + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + /* *** upper box*** */ + + /* get needed box height */ + box_y = metadata_box_height_get(ibuf, fontid, true); + + if (box_y) { + glColor3f(0.1f, 0.1f, 0.1f); + //glColor3f(1.0f, 0.15f, 0.8f); /* Pinkyfied version for Pablo */ + + /* set up rect */ + BLI_rcti_init(&rect, 0, ibuf->x, ibuf->y, ibuf->y + box_y); + /* draw top box */ + glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(fontid, BLF_CLIPPING); + + glColor3f(1.0f, 1.0f, 1.0f); + + metadata_draw_lines(ibuf, rect, fontid, true); + + BLF_disable(fontid, BLF_CLIPPING); + } + + + /* *** lower box*** */ + + box_y = metadata_box_height_get(ibuf, fontid, false); + + if (box_y) { + glColor3f(0.1f, 0.1f, 0.1f); + //glColor3f(1.0f, 0.15f, 0.8f); /* Pinkyfied version for Pablo */ + + /* set up box rect */ + BLI_rcti_init(&rect, 0, ibuf->x, -box_y, 0); + /* draw top box */ + glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(fontid, BLF_CLIPPING); + + glColor3f(1.0f, 1.0f, 1.0f); + + metadata_draw_lines(ibuf, rect, fontid, false); + + BLF_disable(fontid, BLF_CLIPPING); + } + + glPopMatrix(); +} + void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) { float gridsize, gridstep = 1.0f / 32.0f; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 5a3c3e90618..04e874bbae1 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -836,14 +836,23 @@ void draw_image_main(const bContext *C, ARegion *ar) ibuf = ED_space_image_acquire_buffer(sima, &lock); /* draw the image or grid */ - if (ibuf == NULL) + if (ibuf == NULL) { ED_region_grid_draw(ar, zoomx, zoomy); - else if (sima->flag & SI_DRAW_TILE) - draw_image_buffer_repeated(C, sima, ar, scene, ima, ibuf, zoomx, zoomy); - else if (ima && (ima->tpageflag & IMA_TILES)) - draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); - else - draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy); + } + else { + + if (sima->flag & SI_DRAW_TILE) + draw_image_buffer_repeated(C, sima, ar, scene, ima, ibuf, zoomx, zoomy); + else if (ima && (ima->tpageflag & IMA_TILES)) + draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); + else + draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy); + + if (sima->flag & SI_DRAW_METADATA) + ED_region_image_metadata_draw(ar, ibuf, zoomx, zoomy); + } + + ED_space_image_release_buffer(sima, ibuf, lock); /* paint helpers */ if (show_paint) @@ -866,8 +875,6 @@ void draw_image_main(const bContext *C, ARegion *ar) } #endif - ED_space_image_release_buffer(sima, ibuf, lock); - if (show_viewer) { BLI_unlock_thread(LOCK_DRAW_IMAGE); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 756f90fe560..2fe2e6615a6 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1672,6 +1672,12 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI goto cleanup; } } + if (1) { + Scene *scene = CTX_data_scene(C); + if (scene && scene->camera) { + BKE_imbuf_stamp_info(scene, scene->camera, ibuf); + } + } } /* fancy multiview OpenEXR */ @@ -1693,6 +1699,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI } else { colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); + IMB_metadata_copy(colormanaged_ibuf, ibuf); ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, imf, save_copy); save_imbuf_post(ibuf, colormanaged_ibuf); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 32584a3a2df..a9a5e601e10 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -683,7 +683,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) View2D *v2d = &ar->v2d; //View2DScrollers *scrollers; float col[3]; - + /* XXX not supported yet, disabling for now */ scene->r.scemode &= ~R_COMP_CROP; diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index f4189a18da4..d1495d85e64 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../blenkernel ../../blenlib ../../bmesh + ../../imbuf ../../gpu ../../makesdna ../../makesrna diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index a39832dd1cb..7c7f2db09d2 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -547,8 +547,21 @@ void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, const float col[4], struct ColorManagedDisplay *display, int x1, int y1, int x2, int y2); -/* defined in metadata.c */ +/** + * + * \attention Defined in metadata.c + */ +/** read the field from the image info into the field + * \param img - the ImBuf that contains the image data + * \param key - the key of the field + * \param value - the data in the field, first one found with key is returned, + * memory has to be allocated by user. + * \param len - length of value buffer allocated by user. + * \return - 1 (true) if ImageInfo present and value for the key found, 0 (false) otherwise + */ +bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *value, const size_t len); bool IMB_metadata_change_field(struct ImBuf *img, const char *key, const char *field); +void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb); /* exported for image tools in blender, to quickly allocate 32 bits rect */ bool imb_addrectImBuf(struct ImBuf *ibuf); diff --git a/source/blender/imbuf/intern/IMB_metadata.h b/source/blender/imbuf/intern/IMB_metadata.h index 5d4a0028ee1..bc0b2c70ecb 100644 --- a/source/blender/imbuf/intern/IMB_metadata.h +++ b/source/blender/imbuf/intern/IMB_metadata.h @@ -47,16 +47,6 @@ struct ImBuf; /* free blender ImMetaData struct */ void IMB_metadata_free(struct ImBuf *img); -/** read the field from the image info into the field - * \param img - the ImBuf that contains the image data - * \param key - the key of the field - * \param value - the data in the field, first one found with key is returned, - * memory has to be allocated by user. - * \param len - length of value buffer allocated by user. - * \return - 1 (true) if ImageInfo present and value for the key found, 0 (false) otherwise - */ -bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *value, const size_t len); - /** set user data in the ImMetaData struct, which has to be allocated with IMB_metadata_create * before calling this function. * \param img - the ImBuf that contains the image data diff --git a/source/blender/imbuf/intern/metadata.c b/source/blender/imbuf/intern/metadata.c index 8cb5070dd62..134bbe88f15 100644 --- a/source/blender/imbuf/intern/metadata.c +++ b/source/blender/imbuf/intern/metadata.c @@ -79,6 +79,13 @@ bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *field, con return retval; } +void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb) +{ + if (simb->metadata) { + dimb->metadata = IDP_CopyProperty(simb->metadata); + } +} + bool IMB_metadata_add_field(struct ImBuf *img, const char *key, const char *value) { IDProperty *prop; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 29b78c158fd..09651bdbf3a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -834,6 +834,7 @@ typedef enum eSpaceImage_Flag { SI_COLOR_CORRECTION = (1 << 24), SI_NO_DRAW_TEXPAINT = (1 << 25), + SI_DRAW_METADATA = (1 << 26) } eSpaceImage_Flag; /* Text Editor ============================================ */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index e174d1ce5d0..fd03840b145 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1917,6 +1917,11 @@ static void rna_def_space_image_uv(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Other Objects", "Draw other selected objects that share the same image"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "show_metadata", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_METADATA); + RNA_def_property_ui_text(prop, "Draw Metadata", "Draw metadata properties of the image"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "show_texpaint", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SI_NO_DRAW_TEXPAINT); RNA_def_property_ui_text(prop, "Draw Texture Paint UVs", "Draw overlay of texture paint uv layer"); |