Skip to content

Commit

Permalink
Added a TMX rasterizer
Browse files Browse the repository at this point in the history
Renders a map with a specified scale, without collision layer and object
groups.
  • Loading branch information
vincent-petithory authored and bjorn committed Dec 27, 2012
1 parent 9500db7 commit 5d49e77
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
build
bin/automappingconverter
bin/tiled
bin/tmxrasterizer
bin/tmxviewer
lib/tiled/plugins/*
lib/*.so*
Expand All @@ -16,6 +17,7 @@ docs/html

# Build artifacts on Windows
tiled.exe
tmxrasterizer.exe
tmxviewer.exe
automappingconverter.exe
*.dll
Expand Down
2 changes: 2 additions & 0 deletions dist/win/tiled.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ File /oname=LICENSE.GPL.txt ${ROOT_DIR}\LICENSE.GPL
File ${BUILD_DIR}\${P_NORM}.dll
File ${BUILD_DIR}\${P_NORM}.exe
File ${BUILD_DIR}\tmxviewer.exe
File ${BUILD_DIR}\tmxrasterizer.exe
File ${BUILD_DIR}\automappingconverter.exe
File ${MINGW_DIR}\bin\mingwm10.dll
File ${MINGW_DIR}\bin\libgcc_s_dw2-1.dll
Expand Down Expand Up @@ -251,6 +252,7 @@ Delete $INSTDIR\LICENSE.LGPL.txt
Delete $INSTDIR\tiled.dll
Delete $INSTDIR\tiled.exe
Delete $INSTDIR\tmxviewer.exe
Delete $INSTDIR\tmxrasterizer.exe
Delete $INSTDIR\automappingconverter.exe
Delete $INSTDIR\mingwm10.dll
Delete $INSTDIR\libgcc_s_dw2-1.dll
Expand Down
1 change: 1 addition & 0 deletions src/src.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ CONFIG += ordered

SUBDIRS = libtiled tiled plugins \
tmxviewer \
tmxrasterizer \
automappingconverter
169 changes: 169 additions & 0 deletions src/tmxrasterizer/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* main.cpp
* Copyright 2012, Vincent Petithory <[email protected]>
*
* This file is part of the TMX Rasterizer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "tmxrasterizer.h"

#include <QApplication>
#include <QDebug>
#include <QStringList>

namespace {

struct CommandLineOptions {
CommandLineOptions()
: showHelp(false)
, showVersion(false)
{}

bool showHelp;
bool showVersion;
QString fileToOpen;
QString fileToSave;
qreal scale;
int tileSize;
bool useAntiAliasing;
};

} // anonymous namespace

static void showHelp()
{
// TODO: Make translatable
qWarning() <<
"Usage:\n"
" tmxrasterizer [options] [input file] [output file]\n"
"\n"
"Options:\n"
" -h --help : Display this help\n"
" -v --version : Display the version\n"
" -s --scale SCALE : The scale of the output image\n"
" -t --tilesize SIZE : The requested size in pixels at which a tile is rendered\n"
" Overrides the --scale option\n"
" -a --anti-aliasing : Smooth the output image using anti-aliasing\n";
}

static void showVersion()
{
qWarning() << "TMX Map Rasterizer"
<< qPrintable(QApplication::applicationVersion());
}

static void parseCommandLineArguments(CommandLineOptions &options)
{
const QStringList arguments = QCoreApplication::arguments();
options.scale = 0.0;
options.tileSize = 0;
options.useAntiAliasing = false;
for (int i = 1; i < arguments.size(); ++i) {
const QString &arg = arguments.at(i);
if (arg == QLatin1String("--help") || arg == QLatin1String("-h")) {
options.showHelp = true;
} else if (arg == QLatin1String("--version")
|| arg == QLatin1String("-v")) {
options.showVersion = true;
} else if (arg == QLatin1String("--scale")
|| arg == QLatin1String("-s")) {
i++;
if (i >= arguments.size()) {
options.showHelp = true;
} else {
bool scaleIsDouble;
options.scale = arguments.at(i).toDouble(&scaleIsDouble);
if (!scaleIsDouble) {
qWarning() << arguments.at(i) << ": the specified scale is not a number.";
options.showHelp = true;
}
}
} else if (arg == QLatin1String("--tilesize")
|| arg == QLatin1String("-t")) {
i++;
if (i >= arguments.size()) {
options.showHelp = true;
} else {
bool tileSizeIsInt;
options.tileSize = arguments.at(i).toInt(&tileSizeIsInt);
if (!tileSizeIsInt) {
qWarning() << arguments.at(i) << ": the specified tile size is not an integer.";
options.showHelp = true;
}
}
} else if (arg == QLatin1String("--anti-aliasing")
|| arg == QLatin1String("-a")) {
options.useAntiAliasing = true;
} else if (arg.isEmpty()) {
options.showHelp = true;
} else if (arg.at(0) == QLatin1Char('-')) {
qWarning() << "Unknown option" << arg;
options.showHelp = true;
} else if (options.fileToOpen.isEmpty()) {
options.fileToOpen = arg;
} else if (options.fileToSave.isEmpty()) {
options.fileToSave = arg;
} else {
// All args are already defined. Show help.
options.showHelp = true;
}
}
}

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

a.setOrganizationDomain(QLatin1String("mapeditor.org"));
a.setApplicationName(QLatin1String("TmxRasterizer"));
a.setApplicationVersion(QLatin1String("1.0"));

CommandLineOptions options;
parseCommandLineArguments(options);

if (options.showVersion) {
showVersion();
return 0;
}
if (options.showHelp || (options.fileToOpen.isEmpty() || options.fileToOpen.isEmpty())) {
showHelp();
return 0;
}
if (options.scale <= 0.0 && options.tileSize <= 0) {
showHelp();
return 0;
}

TmxRasterizer w;
w.setAntiAliasing(options.useAntiAliasing);

if (options.tileSize > 0) {
w.setTileSize(options.tileSize);
} else if (options.scale > 0.0) {
w.setScale(options.scale);
}

w.render(options.fileToOpen, options.fileToSave);
return 0;
}
126 changes: 126 additions & 0 deletions src/tmxrasterizer/tmxrasterizer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* tmxrasterizer.cpp
* Copyright 2012, Vincent Petithory <[email protected]>
*
* This file is part of the TMX Rasterizer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "tmxrasterizer.h"

#include "imagelayer.h"
#include "isometricrenderer.h"
#include "map.h"
#include "mapreader.h"
#include "objectgroup.h"
#include "orthogonalrenderer.h"
#include "staggeredrenderer.h"
#include "tilelayer.h"

#include <QDebug>

using namespace Tiled;

TmxRasterizer::TmxRasterizer():
mScale(1.0),
mTileSize(0),
mUseAntiAliasing(true)
{
}

TmxRasterizer::~TmxRasterizer()
{
}

void TmxRasterizer::render(const QString& mapFileName, const QString& bitmapFileName)
{
Map *map;
MapRenderer *renderer;
MapReader reader;
map = reader.readMap(mapFileName);
if (!map) {
qWarning() << "Error while reading" << mapFileName << ":\n" << reader.errorString();
return;
}

switch (map->orientation()) {
case Map::Isometric:
renderer = new IsometricRenderer(map);
break;
case Map::Staggered:
renderer = new StaggeredRenderer(map);
case Map::Orthogonal:
default:
renderer = new OrthogonalRenderer(map);
break;
}

qreal xScale, yScale;

if (mTileSize > 0) {
xScale = (qreal) mTileSize/map->tileWidth();
yScale = (qreal) mTileSize/map->tileHeight();
} else {
xScale = yScale = mScale;
}

QSize mapSize = renderer->mapSize();
mapSize.rwidth() *= xScale;
mapSize.rheight() *= yScale;

QImage image(mapSize, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);

if (xScale != qreal(1) || yScale != qreal(1)) {
if (mUseAntiAliasing) {
painter.setRenderHints(QPainter::SmoothPixmapTransform |
QPainter::Antialiasing);
}
painter.setTransform(QTransform::fromScale(xScale, yScale));
}
// Perform a similar rendering than found in saveasimagedialog.cpp
foreach (Layer *layer, map->layers()) {
// Exclude all object groups and collision layers
if (layer->isObjectGroup() || layer->name().toLower() == "collision")
continue;

painter.setOpacity(layer->opacity());

const TileLayer *tileLayer = dynamic_cast<const TileLayer*>(layer);
const ImageLayer *imageLayer = dynamic_cast<const ImageLayer*>(layer);

if (tileLayer) {
renderer->drawTileLayer(&painter, tileLayer);
} else if (imageLayer) {
renderer->drawImageLayer(&painter, imageLayer);
}
}

// Save image
image.save(bitmapFileName);

delete renderer;
qDeleteAll(map->tilesets());
delete map;
}
57 changes: 57 additions & 0 deletions src/tmxrasterizer/tmxrasterizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* tmxrasterizer.h
* Copyright 2012, Vincent Petithory <[email protected]>
*
* This file is part of the TMX Rasterizer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef TMXRASTERIZER_H
#define TMXRASTERIZER_H

#include <QString>

class TmxRasterizer
{

public:
TmxRasterizer();
~TmxRasterizer();

qreal scale() const { return mScale; }
int tileSize() const { return mTileSize; }
bool useAntiAliasing() const { return mUseAntiAliasing; }

void setScale(qreal scale) { mScale = scale; }
void setTileSize(int tileSize) { mTileSize = tileSize; }
void setAntiAliasing(bool useAntiAliasing) { mUseAntiAliasing = useAntiAliasing; }

void render(const QString &mapFileName, const QString &bitmapFileName);

private:
qreal mScale;
int mTileSize;
bool mUseAntiAliasing;
};

#endif // TMXRASTERIZER_H
Loading

0 comments on commit 5d49e77

Please sign in to comment.