From 59c2e8906a5cb64b55f29d656a5a27366ace38a0 Mon Sep 17 00:00:00 2001 From: "Daniel J. Ramirez" Date: Fri, 17 Nov 2017 21:42:14 -0600 Subject: [PATCH] Improved packed scene previews. --- core/image.cpp | 23 ++++++++++++++++------- core/image.h | 1 + editor/editor_node.cpp | 34 ++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/core/image.cpp b/core/image.cpp index 42684e7ea73..422c0e407b0 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -757,22 +757,24 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { _copy_internals_from(dst); } -void Image::crop(int p_width, int p_height) { +void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { if (!_can_modify(format)) { ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats."); ERR_FAIL(); } + ERR_FAIL_COND(p_x < 0); + ERR_FAIL_COND(p_y < 0); ERR_FAIL_COND(p_width <= 0); ERR_FAIL_COND(p_height <= 0); - ERR_FAIL_COND(p_width > MAX_WIDTH); - ERR_FAIL_COND(p_height > MAX_HEIGHT); + ERR_FAIL_COND(p_x + p_width > MAX_WIDTH); + ERR_FAIL_COND(p_y + p_height > MAX_HEIGHT); /* to save memory, cropping should be done in-place, however, since this function will most likely either not be used much, or in critical areas, for now it wont, because it's a waste of time. */ - if (p_width == width && p_height == height) + if (p_width == width && p_height == height && p_x == 0 && p_y == 0) return; uint8_t pdata[16]; //largest is 16 @@ -784,9 +786,11 @@ void Image::crop(int p_width, int p_height) { PoolVector::Read r = data.read(); PoolVector::Write w = dst.data.write(); - for (int y = 0; y < p_height; y++) { + int m_h = p_y + p_height; + int m_w = p_x + p_width; + for (int y = p_y; y < m_h; y++) { - for (int x = 0; x < p_width; x++) { + for (int x = p_x; x < m_w; x++) { if ((x >= width || y >= height)) { for (uint32_t i = 0; i < pixel_size; i++) @@ -795,7 +799,7 @@ void Image::crop(int p_width, int p_height) { _get_pixelb(x, y, pixel_size, r.ptr(), pdata); } - dst._put_pixelb(x, y, pixel_size, w.ptr(), pdata); + dst._put_pixelb(x - p_x, y - p_y, pixel_size, w.ptr(), pdata); } } } @@ -805,6 +809,11 @@ void Image::crop(int p_width, int p_height) { _copy_internals_from(dst); } +void Image::crop(int p_width, int p_height) { + + crop_from_point(0, 0, p_width, p_height); +} + void Image::flip_y() { if (!_can_modify(format)) { diff --git a/core/image.h b/core/image.h index 27df65a8989..24693aa7064 100644 --- a/core/image.h +++ b/core/image.h @@ -207,6 +207,7 @@ public: /** * Crop the image to a specific size, if larger, then the image is filled by black */ + void crop_from_point(int p_x, int p_y, int p_width, int p_height); void crop(int p_width, int p_height); void flip_x(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 777aedefd27..0cec380fc1f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -906,23 +906,29 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); preview_size *= EDSCALE; - int width, height; - if (img->get_width() > preview_size && img->get_width() >= img->get_height()) { - width = preview_size; - height = img->get_height() * preview_size / img->get_width(); - } else if (img->get_height() > preview_size && img->get_height() >= img->get_width()) { - - height = preview_size; - width = img->get_width() * preview_size / img->get_height(); - } else { - - width = img->get_width(); - height = img->get_height(); - } + // consider a square region + int vp_size = MIN(img->get_width(), img->get_height()); + int x = (img->get_width() - vp_size) / 2; + int y = (img->get_height() - vp_size) / 2; img->convert(Image::FORMAT_RGB8); - img->resize(width, height); + + if (vp_size < preview_size) { + // just square it. + img->crop_from_point(x, y, vp_size, vp_size); + } else { + int ratio = vp_size / preview_size; + int size = preview_size * (ratio / 2); + + x = (img->get_width() - size) / 2; + y = (img->get_height() - size) / 2; + + img->crop_from_point(x, y, size, size); + // We could get better pictures with better filters + img->resize(preview_size, preview_size, Image::INTERPOLATE_CUBIC); + } + img->flip_y(); //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5