mapeditor / tiled

Flexible level editor
https://www.mapeditor.org/
Other
11.24k stars 1.76k forks source link

Exporting image includes enormous amount of whitespace #2151

Open Sheepyhead opened 5 years ago

Sheepyhead commented 5 years ago

Maps.zip I created a tileset using approximately 40 2000x2000 jpgs (each about 2-4MB in size), then created an infinite map using those tiles. Once I settled on what the final map was going to look like, I attempted to export the map as an image, only to receive an image filled with primarily whitespace and my map in the lower right corner of the image, see attached. No matter whether I set it to finite and crop to only include my tiles, the export as image functionality still comes out like this. I have a single tile layer of only one type of visible tile and nothing drawn outside of the 15 connected tiles I drew. I'll attach the map and tileset files as well, though I'm afraid I can't provide the pictures, any 2000x2000 should work to recreate it. I expected the function to only export visible tiles and for the exported picture to consist primarily of the map I drew. Another thing I noticed is that if I zoom in enough, Tiled will complain that it needs 10+ GB of memory to export as image, but the final image is at most 10-11MB. This may be functioning as intended, I don't know. I'm working on a Windows 10 Pro x64 machine on Tiled version 1.2.4.

bjorn commented 5 years ago

One issue is definitely that exporting infinite maps as image leads to larger images than necessary because the size is grown in chunks. I've realized this issue before: https://github.com/bjorn/tiled/issues/1893#issuecomment-371279788. I'll make sure to address that soon. A workaround should be to disable infinite and then to resize the map to the desired size.

Another thing I noticed is that if I zoom in enough, Tiled will complain that it needs 10+ GB of memory to export as image, but the final image is at most 10-11MB.

The memory required is for the complete uncompressed image, which can exceed by far the size of the final image, especially if the image contains large areas with little variation. This complaint only shows up if Tiled is indeed unable to actually save this image. There's two stages involved here:

https://github.com/bjorn/tiled/blob/153405db2a3d279ec744cfd6ffb3f5dda341e315/src/tiled/exportasimagedialog.cpp#L176-L204

So when image.isNull() returns true, it means the image is too large for QImage. In this case, try a development snapshot, because I believe in recent versions of Qt the maximum size supported by QImage was increased a lot and the snapshots are using Qt 5.12 instead of Qt 5.9.

The second stage is when std::bad_alloc is thrown, which means the operating system failed to give Tiled enough memory. As the message says, using the 64-bit build can help here, and if you're already doing that, buying more RAM could help. Or reconsider whether you really need to create such huge images. :-)

Sheepyhead commented 5 years ago

Yeah the size thing was just something I added in in the case that it gave a hint as to the nature of the bug.

Like I described, I have attempted changing the map to a finite map and cropped it to be exactly as large as to cover all my visible tiles, but that seemingly makes no difference.

bjorn commented 5 years ago

I'll attach the map and tileset files as well, though I'm afraid I can't provide the pictures, any 2000x2000 should work to recreate it.

Just for reference, those tiles are part of the Free Big Cave Maptiles collection by Madcowchef on DeviantArt.

So far I have not found any clear information on the license of these assets, but at least we can refer to them and it should be fine to use them for testing. The only thing I found was this quote from the author:

"Yup anything in my free folder can be used for projects if you like. My commercial (thus not free) stuff is in my roll20 folder. Though you can't use them to compete with me by reselling them as is as an art pack that's dirty pool."

bjorn commented 5 years ago

Alright, I could reproduce the issue, and it wasn't related to infinite maps or chunks in this case, but it was due to the enormous horizontal and vertical offset of your tile layer.

At the moment, offsetting a layer only increases the size of the image (to make sure the layer is visible on the exported image), but it does not decrease the image on the other side (based on the assumption that at least the base map should be included in the export). I'm not sure if it makes sense to adjust the algorithm to account for values like in this issue.

Probably this horizontal and vertical offset was unintentional, right? Since I don't see a reason for this. Likely it was due to accidental use of the Offset Layers (M) tool. The easiest way to remove the offset is by setting them to 0 in the layer properties.