diff --git a/CHANGELOG.md b/CHANGELOG.md index 8af9ff6a..483a88ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d - Fix bug where map group names were hardcoded when creating a new map. - Fix bug in Tileset Editor where multi-tile selections weren't properly painted when clicking on the bottom row of the metatile layers. - Fix bug where line breaks in C headers were not parsed properly. +- Fix bug when exporting tileset images using palettes with duplicate colors. ## [1.2.2] - 2019-05-16 diff --git a/include/ui/imageproviders.h b/include/ui/imageproviders.h index 96896e78..de54e1aa 100644 --- a/include/ui/imageproviders.h +++ b/include/ui/imageproviders.h @@ -10,6 +10,26 @@ QImage getCollisionMetatileImage(Block); QImage getCollisionMetatileImage(int, int); QImage getMetatileImage(uint16_t, Tileset*, Tileset*); QImage getTileImage(uint16_t, Tileset*, Tileset*); -QImage getColoredTileImage(uint16_t, Tileset*, Tileset*, int); +QImage getPalettedTileImage(uint16_t, Tileset*, Tileset*, int); +QImage getGreyscaleTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset); + +static QList greyscalePalette({ + qRgb(0, 0, 0), + qRgb(16, 16, 16), + qRgb(32, 32, 32), + qRgb(48, 48, 48), + qRgb(64, 64, 64), + qRgb(80, 80, 80), + qRgb(96, 96, 96), + qRgb(112, 112, 112), + qRgb(128, 128, 128), + qRgb(144, 144, 144), + qRgb(160, 160, 160), + qRgb(176, 176, 176), + qRgb(192, 192, 192), + qRgb(208, 208, 208), + qRgb(224, 224, 224), + qRgb(240, 240, 240), +}); #endif // IMAGEPROVIDERS_H diff --git a/src/ui/imageproviders.cpp b/src/ui/imageproviders.cpp index a72c7a9b..50853793 100644 --- a/src/ui/imageproviders.cpp +++ b/src/ui/imageproviders.cpp @@ -80,8 +80,7 @@ QImage getTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTi return tileset->tiles->value(local_index, QImage()); } -QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId) { - QList palette = Tileset::getPalette(paletteId, primaryTileset, secondaryTileset); +QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, QList palette) { QImage tileImage = getTileImage(tile, primaryTileset, secondaryTileset); if (tileImage.isNull()) { tileImage = QImage(16, 16, QImage::Format_RGBA8888); @@ -95,3 +94,12 @@ QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *seco return tileImage; } + +QImage getPalettedTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId) { + QList palette = Tileset::getPalette(paletteId, primaryTileset, secondaryTileset); + return getColoredTileImage(tile, primaryTileset, secondaryTileset, palette); +} + +QImage getGreyscaleTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) { + return getColoredTileImage(tile, primaryTileset, secondaryTileset, greyscalePalette); +} diff --git a/src/ui/metatilelayersitem.cpp b/src/ui/metatilelayersitem.cpp index 68a58492..774e1388 100644 --- a/src/ui/metatilelayersitem.cpp +++ b/src/ui/metatilelayersitem.cpp @@ -18,7 +18,7 @@ void MetatileLayersItem::draw() { QPainter painter(&pixmap); for (int i = 0; i < 8; i++) { Tile tile = this->metatile->tiles->at(i); - QImage tileImage = getColoredTileImage(tile.tile, this->primaryTileset, this->secondaryTileset, tile.palette) + QImage tileImage = getPalettedTileImage(tile.tile, this->primaryTileset, this->secondaryTileset, tile.palette) .mirrored(tile.xflip, tile.yflip) .scaled(16, 16); painter.drawImage(tileCoords.at(i), tileImage); diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index d6293a01..50dd760c 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -152,7 +152,7 @@ void TilesetEditor::drawSelectedTiles() { int tileIndex = 0; for (int j = 0; j < dimensions.y(); j++) { for (int i = 0; i < dimensions.x(); i++) { - QImage tileImage = getColoredTileImage(tiles.at(tileIndex).tile, this->primaryTileset, this->secondaryTileset, tiles.at(tileIndex).palette) + QImage tileImage = getPalettedTileImage(tiles.at(tileIndex).tile, this->primaryTileset, this->secondaryTileset, tiles.at(tileIndex).palette) .mirrored(tiles.at(tileIndex).xflip, tiles.at(tileIndex).yflip) .scaled(16, 16); tileIndex++; diff --git a/src/ui/tileseteditortileselector.cpp b/src/ui/tileseteditortileselector.cpp index e2a52e5e..1c0bd9dd 100644 --- a/src/ui/tileseteditortileselector.cpp +++ b/src/ui/tileseteditortileselector.cpp @@ -29,12 +29,12 @@ void TilesetEditorTileSelector::draw() { for (uint16_t tile = 0; tile < totalTiles; tile++) { QImage tileImage; if (tile < primaryLength) { - tileImage = getColoredTileImage(tile, this->primaryTileset, this->secondaryTileset, this->paletteId).scaled(16, 16); + tileImage = getPalettedTileImage(tile, this->primaryTileset, this->secondaryTileset, this->paletteId).scaled(16, 16); } else if (tile < Project::getNumTilesPrimary()) { tileImage = QImage(16, 16, QImage::Format_RGBA8888); tileImage.fill(palette.at(0)); } else if (tile < Project::getNumTilesPrimary() + secondaryLength) { - tileImage = getColoredTileImage(tile, this->primaryTileset, this->secondaryTileset, this->paletteId).scaled(16, 16); + tileImage = getPalettedTileImage(tile, this->primaryTileset, this->secondaryTileset, this->paletteId).scaled(16, 16); } else { tileImage = QImage(16, 16, QImage::Format_RGBA8888); QPainter painter(&tileImage); @@ -201,17 +201,16 @@ QImage TilesetEditorTileSelector::buildPrimaryTilesIndexedImage() { int primaryLength = this->primaryTileset->tiles->length(); int height = primaryLength / this->numTilesWide; - QList palette = Tileset::getPalette(this->paletteId, this->primaryTileset, this->secondaryTileset); QImage image(this->numTilesWide * 8, height * 8, QImage::Format_RGBA8888); QPainter painter(&image); for (uint16_t tile = 0; tile < primaryLength; tile++) { QImage tileImage; if (tile < primaryLength) { - tileImage = getColoredTileImage(tile, this->primaryTileset, this->secondaryTileset, this->paletteId); + tileImage = getGreyscaleTileImage(tile, this->primaryTileset, this->secondaryTileset); } else { tileImage = QImage(8, 8, QImage::Format_RGBA8888); - tileImage.fill(palette.at(0)); + tileImage.fill(qRgb(0, 0, 0)); } int y = tile / this->numTilesWide; @@ -222,8 +221,12 @@ QImage TilesetEditorTileSelector::buildPrimaryTilesIndexedImage() { painter.end(); - QVector colorTable = palette.toVector(); - return image.convertToFormat(QImage::Format::Format_Indexed8, colorTable); + // Image is first converted using greyscale so that palettes with duplicate colors + // are properly represented in the final image. + QImage indexedImage = image.convertToFormat(QImage::Format::Format_Indexed8, greyscalePalette.toVector()); + QList palette = Tileset::getPalette(this->paletteId, this->primaryTileset, this->secondaryTileset); + indexedImage.setColorTable(palette.toVector()); + return indexedImage; } QImage TilesetEditorTileSelector::buildSecondaryTilesIndexedImage() { @@ -234,7 +237,6 @@ QImage TilesetEditorTileSelector::buildSecondaryTilesIndexedImage() { int secondaryLength = this->secondaryTileset->tiles->length(); int height = secondaryLength / this->numTilesWide; - QList palette = Tileset::getPalette(this->paletteId, this->primaryTileset, this->secondaryTileset); QImage image(this->numTilesWide * 8, height * 8, QImage::Format_RGBA8888); QPainter painter(&image); @@ -242,10 +244,10 @@ QImage TilesetEditorTileSelector::buildSecondaryTilesIndexedImage() { for (uint16_t tile = 0; tile < secondaryLength; tile++) { QImage tileImage; if (tile < secondaryLength) { - tileImage = getColoredTileImage(tile + primaryLength, this->primaryTileset, this->secondaryTileset, this->paletteId); + tileImage = getGreyscaleTileImage(tile + primaryLength, this->primaryTileset, this->secondaryTileset); } else { tileImage = QImage(8, 8, QImage::Format_RGBA8888); - tileImage.fill(palette.at(0)); + tileImage.fill(qRgb(0, 0, 0)); } int y = tile / this->numTilesWide; @@ -256,6 +258,10 @@ QImage TilesetEditorTileSelector::buildSecondaryTilesIndexedImage() { painter.end(); - QVector colorTable = palette.toVector(); - return image.convertToFormat(QImage::Format::Format_Indexed8, colorTable); + // Image is first converted using greyscale so that palettes with duplicate colors + // are properly represented in the final image. + QImage indexedImage = image.convertToFormat(QImage::Format::Format_Indexed8, greyscalePalette.toVector()); + QList palette = Tileset::getPalette(this->paletteId, this->primaryTileset, this->secondaryTileset); + indexedImage.setColorTable(palette.toVector()); + return indexedImage; }