• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Export RME map

Status
Not open for further replies.

leonardovsilva

New Member
Joined
Apr 21, 2022
Messages
6
Reaction score
2
Can someone help me? I’d like to export that RME view into a high-scale PNG. Does anyone know how to do this?


I was looking at the RME code and got stuck.
When it retrieves the Tile, how could I write this into the image buffer?
I was thinking of an 8x image, meaning 32/4.

bool IOMinimap::exportMinimap(const std::string& directory)
{
auto& map = m_editor->getMap();
if(map.size() == 0) {
return true;
}

wxRect bounds[rme::MapLayers];
int min_z = m_floor == -1 ? 0 : m_floor;
int max_z = m_floor == -1 ? rme::MapMaxLayer : m_floor;

for (size_t z = min_z; z <= max_z; z++) {
auto& rect = bounds[z];
rect.x = rme::MapMaxWidth + 1;
rect.y = rme::MapMaxHeight + 1;
rect.width = 0;
rect.height = 0;
}

for(auto it = map.begin(); it != map.end(); ++it) {
auto tile = (*it)->get();
if(!tile || (!tile->ground && tile->items.empty())) {
continue;
}

const auto& position = tile->getPosition();
auto& rect = bounds[position.z];
if(position.x < rect.x) {
rect.x = position.x;
}
if(position.y < rect.y) {
rect.y = position.y;
}
if (position.x > rect.width) {
rect.width = position.x;
}
if (position.y > rect.height) {
rect.height = position.y;
}
}

constexpr int image_size = 1024;
constexpr int pixels_size = image_size * image_size * rme::PixelFormatRGB;
uint8_t* pixels = new uint8_t[pixels_size];
auto image = new wxImage(image_size, image_size, pixels, true);

for(size_t z = min_z; z <= max_z; z++) {
auto& rect = bounds[z];
if(rect.IsEmpty()) {
continue;
}

for (int h = 0; h < rme::MapMaxHeight; h += image_size) {
for (int w = 0; w < rme::MapMaxWidth; w += image_size) {
if (w < rect.x || w > rect.width || h < rect.y || h > rect.height) {
continue;
}

bool empty = true;
memset(pixels, 0, pixels_size);

int index = 0;
for (int y = 0; y < image_size; y++) {
for (int x = 0; x < image_size; x++) {
auto tile = map.getTile(w + x, h + y, z);
if(!tile || (!tile->ground && tile->items.empty())) {
index += rme::PixelFormatRGB;
continue;
}
uint8_t color = tile->getMiniMapColor();
pixels[index ] = (uint8_t)(static_cast<int>(color / 36) % 6 * 51); // red
pixels[index+1] = (uint8_t)(static_cast<int>(color / 6) % 6 * 51); // green
pixels[index+2] = (uint8_t)(color % 6 * 51); // blue
index += rme::PixelFormatRGB;
empty = false;
}
}

if (!empty) {
image->SetData(pixels, true);
wxString extension = m_format == MinimapExportFormat::Png ? "png" : "bmp";
wxBitmapType type = m_format == MinimapExportFormat::Png ? wxBITMAP_TYPE_PNG : wxBITMAP_TYPE_BMP;
wxFileName file = wxString::Format("%d-%d-%d.%s", h, w, z, extension);
file.Normalize(wxPATH_NORM_ALL, directory);
image->SaveFile(file.GetFullPath(), type);
}
}
}
}

image->Destroy();
delete[] pixels;
return true;
}
 
Last edited:
How to export RME map to image: answer from private conversation with @leonardovsilva

You must use https://github.com/gesior/otclient_mapgen/releases/download/v5.1/otclient_mapgen_v5.1_win-x64.zip
Example of big image with TFS 1.4 files and Tibia 10.98 files put into data/things/1098/:
Code:
prepareClient(1098, '/things/1098/items.otb', '/things/1098/forgotten.otbm', 1, 1)
wait until it load.
Then (you can paste all these lines as 1 line into OTClient terminal, it will work):
Code:
g_map.setMinXToLoad(0)
g_map.setMaxXToLoad(70000)
g_map.setMinXToRender(0)
g_map.setMaxXToRender(70000)
g_map.loadOtbm('/things/1098/forgotten.otbm')
and to generate 100x100 SQM image from position x=100, y= 350, z =7 to x = 200, y= 450, z =7 (3200x3200 px):
Code:
g_map.drawCustomMap("100x100.png", 100, 350, 7, 200, 450, true);
Last parameter true is to render lower floors.
I generated 100x100 and 200x200 images and uploaded here:

I've tested it with 500x500 SQM and it used 1 GB RAM and took 20 seconds (freez client) to generate 60 MB PNG file.
I cannot run much higher parameters (ex. 1000x1000), so maybe there is something in C++ that limits size of image to 22400x22400 pixels (700x700 tiles) or maybe it's problem with OTS map that has no more items after ~700x600 SQM.
 
Thank you, Gesior! This function is very helpful for anyone who wants to have the map image in a single format, whether it's for creating graphic art on top of it or customizing the map in the project.
 
How to export RME map to image: answer from private conversation with @leonardovsilva

You must use https://github.com/gesior/otclient_mapgen/releases/download/v5.1/otclient_mapgen_v5.1_win-x64.zip
Example of big image with TFS 1.4 files and Tibia 10.98 files put into data/things/1098/:
Code:
prepareClient(1098, '/things/1098/items.otb', '/things/1098/forgotten.otbm', 1, 1)
wait until it load.
Then (you can paste all these lines as 1 line into OTClient terminal, it will work):
Code:
g_map.setMinXToLoad(0)
g_map.setMaxXToLoad(70000)
g_map.setMinXToRender(0)
g_map.setMaxXToRender(70000)
g_map.loadOtbm('/things/1098/forgotten.otbm')
and to generate 100x100 SQM image from position x=100, y= 350, z =7 to x = 200, y= 450, z =7 (3200x3200 px):
Code:
g_map.drawCustomMap("100x100.png", 100, 350, 7, 200, 450, true);
Last parameter true is to render lower floors.
I generated 100x100 and 200x200 images and uploaded here:

I've tested it with 500x500 SQM and it used 1 GB RAM and took 20 seconds (freez client) to generate 60 MB PNG file.
I cannot run much higher parameters (ex. 1000x1000), so maybe there is something in C++ that limits size of image to 22400x22400 pixels (700x700 tiles) or maybe it's problem with OTS map that has no more items after ~700x600 SQM.
hd mode is just enabling anti-aliasing?
xD
 
Status
Not open for further replies.
Back
Top