Browse Source

Improved packed scene previews.

Daniel J. Ramirez 7 years ago
parent
commit
59c2e8906a
3 changed files with 34 additions and 18 deletions
  1. 16 7
      core/image.cpp
  2. 1 0
      core/image.h
  3. 17 11
      editor/editor_node.cpp

+ 16 - 7
core/image.cpp

@@ -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_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
 	/* 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)) {

+ 1 - 0
core/image.h

@@ -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();

+ 17 - 11
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");
 		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;
-			height = img->get_height() * preview_size / img->get_width();
-		} else if (img->get_height() > preview_size && img->get_height() >= img->get_width()) {
+		// 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;
 
 
-			height = preview_size;
-			width = img->get_width() * preview_size / img->get_height();
+		img->convert(Image::FORMAT_RGB8);
+
+		if (vp_size < preview_size) {
+			// just square it.
+			img->crop_from_point(x, y, vp_size, vp_size);
 		} else {
 		} else {
+			int ratio = vp_size / preview_size;
+			int size = preview_size * (ratio / 2);
 
 
-			width = img->get_width();
-			height = img->get_height();
+			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->convert(Image::FORMAT_RGB8);
-		img->resize(width, height);
 		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