Improved packed scene previews.

This commit is contained in:
Daniel J. Ramirez 2017-11-17 21:42:14 -06:00
parent 62eda56e67
commit 59c2e8906a
3 changed files with 37 additions and 21 deletions

View file

@ -757,22 +757,24 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
_copy_internals_from(dst); _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)) { if (!_can_modify(format)) {
ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats."); ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats.");
ERR_FAIL(); ERR_FAIL();
} }
ERR_FAIL_COND(p_x < 0);
ERR_FAIL_COND(p_y < 0);
ERR_FAIL_COND(p_width <= 0); ERR_FAIL_COND(p_width <= 0);
ERR_FAIL_COND(p_height <= 0); ERR_FAIL_COND(p_height <= 0);
ERR_FAIL_COND(p_width > MAX_WIDTH); ERR_FAIL_COND(p_x + p_width > MAX_WIDTH);
ERR_FAIL_COND(p_height > MAX_HEIGHT); ERR_FAIL_COND(p_y + p_height > MAX_HEIGHT);
/* to save memory, cropping should be done in-place, however, since this function /* 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 will most likely either not be used much, or in critical areas, for now it wont, because
it's a waste of time. */ 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; return;
uint8_t pdata[16]; //largest is 16 uint8_t pdata[16]; //largest is 16
@ -784,9 +786,11 @@ void Image::crop(int p_width, int p_height) {
PoolVector<uint8_t>::Read r = data.read(); PoolVector<uint8_t>::Read r = data.read();
PoolVector<uint8_t>::Write w = dst.data.write(); PoolVector<uint8_t>::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)) { if ((x >= width || y >= height)) {
for (uint32_t i = 0; i < pixel_size; i++) 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); _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); _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() { void Image::flip_y() {
if (!_can_modify(format)) { if (!_can_modify(format)) {

View file

@ -207,6 +207,7 @@ public:
/** /**
* Crop the image to a specific size, if larger, then the image is filled by black * 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 crop(int p_width, int p_height);
void flip_x(); void flip_x();

View file

@ -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"); int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
preview_size *= EDSCALE; preview_size *= EDSCALE;
int width, height;
if (img->get_width() > preview_size && img->get_width() >= img->get_height()) {
width = preview_size; // consider a square region
height = img->get_height() * preview_size / img->get_width(); int vp_size = MIN(img->get_width(), img->get_height());
} else if (img->get_height() > preview_size && img->get_height() >= img->get_width()) { int x = (img->get_width() - vp_size) / 2;
int y = (img->get_height() - vp_size) / 2;
height = preview_size;
width = img->get_width() * preview_size / img->get_height();
} else {
width = img->get_width();
height = img->get_height();
}
img->convert(Image::FORMAT_RGB8); 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(); img->flip_y();
//save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5