int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); #ifndef Q_OS_WIN32 QTranslator translator; QTranslator qtTranslator; QString sysLocale = QLocale::system().name(); QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir) && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) { app.installTranslator(&translator); app.installTranslator(&qtTranslator); } #endif // Q_OS_WIN32 QStringList args = app.arguments(); QList<File> inFiles; QString inFormat(QLatin1String("auto")); QString outFileName; QString outFormat(QLatin1String("auto")); QString targetLanguage; QString sourceLanguage; bool dropTranslations = false; bool noObsolete = false; bool noFinished = false; bool verbose = false; bool noUiLines = false; Translator::LocationsType locations = Translator::DefaultLocations; ConversionData cd; Translator tr; for (int i = 1; i < args.size(); ++i) { if (args[i].startsWith(QLatin1String("--"))) args[i].remove(0, 1); if (args[i] == QLatin1String("-o") || args[i] == QLatin1String("-output-file")) { if (++i >= args.size()) return usage(args); outFileName = args[i]; } else if (args[i] == QLatin1String("-of") || args[i] == QLatin1String("-output-format")) { if (++i >= args.size()) return usage(args); outFormat = args[i]; } else if (args[i] == QLatin1String("-i") || args[i] == QLatin1String("-input-file")) { if (++i >= args.size()) return usage(args); File file; file.name = args[i]; file.format = inFormat; inFiles.append(file); } else if (args[i] == QLatin1String("-if") || args[i] == QLatin1String("-input-format")) { if (++i >= args.size()) return usage(args); inFormat = args[i]; } else if (args[i] == QLatin1String("-input-codec")) { if (++i >= args.size()) return usage(args); cd.m_codecForSource = args[i].toLatin1(); } else if (args[i] == QLatin1String("-output-codec")) { if (++i >= args.size()) return usage(args); cd.m_outputCodec = args[i].toLatin1(); } else if (args[i] == QLatin1String("-drop-tag")) { if (++i >= args.size()) return usage(args); cd.m_dropTags.append(args[i]); } else if (args[i] == QLatin1String("-drop-translations")) { dropTranslations = true; } else if (args[i] == QLatin1String("-target-language")) { if (++i >= args.size()) return usage(args); targetLanguage = args[i]; } else if (args[i] == QLatin1String("-source-language")) { if (++i >= args.size()) return usage(args); sourceLanguage = args[i]; } else if (args[i].startsWith(QLatin1String("-h"))) { usage(args); return 0; } else if (args[i] == QLatin1String("-no-obsolete")) { noObsolete = true; } else if (args[i] == QLatin1String("-no-finished")) { noFinished = true; } else if (args[i] == QLatin1String("-sort-contexts")) { cd.m_sortContexts = true; } else if (args[i] == QLatin1String("-locations")) { if (++i >= args.size()) return usage(args); if (args[i] == QLatin1String("none")) locations = Translator::NoLocations; else if (args[i] == QLatin1String("relative")) locations = Translator::RelativeLocations; else if (args[i] == QLatin1String("absolute")) locations = Translator::AbsoluteLocations; else return usage(args); } else if (args[i] == QLatin1String("-no-ui-lines")) { noUiLines = true; } else if (args[i] == QLatin1String("-verbose")) { verbose = true; } else if (args[i].startsWith(QLatin1Char('-'))) { return usage(args); } else { File file; file.name = args[i]; file.format = inFormat; inFiles.append(file); } } if (inFiles.isEmpty()) return usage(args); tr.setLanguageCode(Translator::guessLanguageCodeFromFileName(inFiles[0].name)); if (!tr.load(inFiles[0].name, cd, inFiles[0].format)) { std::cerr << qPrintable(cd.error()); return 2; } tr.reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose); for (int i = 1; i < inFiles.size(); ++i) { Translator tr2; if (!tr2.load(inFiles[i].name, cd, inFiles[i].format)) { std::cerr << qPrintable(cd.error()); return 2; } tr2.reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose); for (int j = 0; j < tr2.messageCount(); ++j) tr.replaceSorted(tr2.message(j)); } if (!targetLanguage.isEmpty()) tr.setLanguageCode(targetLanguage); if (!sourceLanguage.isEmpty()) tr.setSourceLanguageCode(sourceLanguage); if (noObsolete) tr.stripObsoleteMessages(); if (noFinished) tr.stripFinishedMessages(); if (dropTranslations) tr.dropTranslations(); if (noUiLines) tr.dropUiLines(); if (locations != Translator::DefaultLocations) tr.setLocationsType(locations); tr.normalizeTranslations(cd); if (!cd.errors().isEmpty()) { std::cerr << qPrintable(cd.error()); cd.clearErrors(); } if (!tr.save(outFileName, cd, outFormat)) { std::cerr << qPrintable(cd.error()); return 3; } return 0; }
int main(int argc, char *argv[]) { QApplication a(argc, argv); imageExtensions << "bmp" << "png" << "jpg" << "jpeg"; //command-line version if(argc > 1) { int textureWidth = 512; int textureHeight = 512; bool merge = true; bool crop = true; int border = 1; int extrude = 0; bool rotate = false; bool recursion = true; bool square = false; bool autosize = false; int cropThreshold = 1; int autosizeThreshold = 80; int minTextureSizeX = 32; int minTextureSizeY = 32; int sortorder = 4; ImagePacker packer; mainPacker = &packer; QString outDir = QDir::currentPath(); QString outFile = "atlas"; for(int i = 1; i < argc; ++i) { if(check_opt("--help") || check_opt("-h") || check_opt("-?")) { printHelp(); } else if(check_opt("-s") || check_opt("--size")) { ++i; if(i >= argc) { printHelp("Argument needed for option -s"); } if(sscanf(argv[i], "%10dx%10d", &textureWidth, &textureHeight) != 2) { if(sscanf(argv[i], "%10d", &textureWidth) != 1) { printHelp("Wrong texture size format"); } else { textureHeight = textureWidth; } } printf("Setting texture size: %dx%d\n", textureWidth, textureHeight); } else if(check_opt("-o") || check_opt("--out-file")) { ++i; if(i >= argc) { printHelp("Argument needed for option -o"); } QFileInfo info(argv[i]); outFile = info.baseName(); outDir = info.absolutePath(); } else if(check_opt("--disable-merge")) { merge = false; } else if(check_opt("--disable-crop")) { crop = false; } else if(check_opt("--disable-recursion")) { recursion = false; } else if(check_opt("--square")) { square = true; } else if(check_opt("--autosize-threshold")) { autosize = true; ++i; if(i >= argc) { printHelp("Argument needed for option --autosize-threshold"); } if((sscanf(argv[i], "%10d", &autosizeThreshold) != 1) || (autosizeThreshold < 0) || (autosizeThreshold > 100)) { printHelp("Wrong autosize threshold"); } } else if(check_opt("--extrude-size")) { ++i; if(i >= argc) { printHelp("Argument needed for option --extrude-size"); } if((sscanf(argv[i], "%10d", &extrude) != 1) || (extrude < 0)) { printHelp("Wrong extrude size"); } } else if(check_opt("--border-size")) { ++i; if(i >= argc) { printHelp("Argument needed for option --border-size"); } if((sscanf(argv[i], "%10d", &border) != 1) || (border < 0)) { printHelp("Wrong border size"); } } else if(check_opt("--min-texture-size")) { ++i; if(i >= argc) { printHelp("Argument needed for option -min-texture-size"); } if(sscanf(argv[i], "%10dx%10d", &minTextureSizeX, &minTextureSizeY) != 2) { if(sscanf(argv[i], "%10d", &minTextureSizeX) != 1) { printHelp("Wrong texture size format"); } else { minTextureSizeY = minTextureSizeX; } } } else if(check_opt("--crop-threshold")) { ++i; if(i >= argc) { printHelp("Argument needed for option --crop-threshold"); } if((sscanf(argv[i], "%10d", &cropThreshold) != 1) || (cropThreshold < 0) || (cropThreshold > 255)) { printHelp("Wrong crop threshold"); } } else if(check_opt("--sort-order")) { ++i; if(i >= argc) { printHelp("Argument needed for option --sort-order"); } if((sscanf(argv[i], "%10d", &sortorder) != 1) || (sortorder < 0) || (sortorder > 4)) { printHelp("Wrong sortorder must be from 0 to 4"); } } else if(check_opt("--disable-border")) { border = 0; } else if(check_opt("--enable-rotate")) { rotate = true; } //dir or file else { QFileInfo file(argv[i]); if(file.isFile()) { packerData *data = new packerData; data->path = file.absoluteFilePath(); data->file = file.fileName(); packer.addItem(data->path, data); } else if(file.isDir()) { topImageDir = file.absoluteFilePath(); RecurseDirectory(file.absoluteFilePath(), recursion); } } } qDebug() << "Saving to dir" << outDir << "and file" << outFile; packer.sortOrder = sortorder; packer.border.t = 0; packer.border.l = 0; packer.border.r = border; packer.border.b = border; packer.extrude = extrude; packer.cropThreshold = crop ? cropThreshold : 0; packer.minFillRate = autosize ? autosizeThreshold : 0; packer.minTextureSizeX = minTextureSizeX; packer.minTextureSizeY = minTextureSizeY; packer.merge = merge; packer.mergeBF = false; packer.rotate = rotate; packer.square = square; packer.autosize = autosize; int heuristic = 1; QString outFormat("PNG"); if(packer.images.size() == 0) { fprintf(stderr, "No images found, exitting\n"); exit(1); } packer.pack(heuristic, textureWidth, textureHeight); QList<QImage> textures; for(int i = 0; i < packer.bins.size(); i++) { QImage texture(packer.bins.at(i).width(), packer.bins.at(i).height(), QImage::Format_ARGB32); texture.fill(Qt::transparent); textures << texture; } for(int j = 0; j < textures.count(); j++) { QString outputFile = outDir; outputFile += QDir::separator(); outputFile += outFile; if(textures.count() > 1) { outputFile += QString("_") + QString::number(j + 1); } outputFile += ".atlas"; QString imgFile = outFile; if(textures.count() > 1) { imgFile += QString("_") + QString::number(j + 1); } imgFile += "."; imgFile += outFormat.toLower(); QFile positionsFile(outputFile); if(!positionsFile.open(QIODevice::WriteOnly | QIODevice::Text)) { fprintf(stderr, "Cannot create file %s", qPrintable(outputFile)); } else { QTextStream out(&positionsFile); out << "textures: " << imgFile << "\n"; for(int i = 0; i < packer.images.size(); i++) { if(packer.images.at(i).textureId != j) { continue; } QPoint pos(packer.images.at(i).pos.x() + packer.border.l + packer.extrude, packer.images.at(i).pos.y() + packer.border.t + packer.extrude); QSize size, sizeOrig; QRect crop; sizeOrig = packer.images.at(i).size; if(!packer.cropThreshold) { size = packer.images.at(i).size; crop = QRect(0, 0, size.width(), size.height()); } else { size = packer.images.at(i).crop.size(); crop = packer.images.at(i).crop; } if(packer.images.at(i).rotated) { size.transpose(); crop = QRect(crop.y(), crop.x(), crop.height(), crop.width()); } out << (static_cast<packerData *>(packer.images.at(i).id))->file << "\t" << pos.x() << "\t" << pos.y() << "\t" << crop.width() << "\t" << crop.height() << "\t" << crop.x() << "\t" << crop.y() << "\t" << sizeOrig.width() << "\t" << sizeOrig.height() << "\t" << (packer.images.at(i).rotated ? "r" : "") << "\n"; } } } for(int i = 0; i < packer.images.size(); i++) { qDebug() << "Processing" << (static_cast<packerData *>(packer.images.at( i).id))->file; if(packer.images.at(i).duplicateId != NULL && packer.merge) { continue; } QPoint pos(packer.images.at(i).pos.x() + packer.border.l, packer.images.at(i).pos.y() + packer.border.t); QSize size; QRect crop; if(!packer.cropThreshold) { size = packer.images.at(i).size; crop = QRect(0, 0, size.width(), size.height()); } else { size = packer.images.at(i).crop.size(); crop = packer.images.at(i).crop; } QImage img; img = QImage((static_cast<packerData *>(packer.images.at(i).id))->path); if(packer.images.at(i).rotated) { QTransform myTransform; myTransform.rotate(90); img = img.transformed(myTransform); size.transpose(); crop = QRect(packer.images.at(i).size.height() - crop.y() - crop.height(), crop.x(), crop.height(), crop.width()); } if(packer.images.at(i).textureId < packer.bins.size()) { QPainter p(&textures.operator [](packer.images.at(i).textureId)); if(packer.extrude) { QColor color1 = QColor::fromRgba(img.pixel(crop.x(), crop.y())); p.setPen(color1); p.setBrush(color1); if(packer.extrude == 1) { p.drawPoint(QPoint(pos.x(), pos.y())); } else { p.drawRect(QRect(pos.x(), pos.y(), packer.extrude - 1, packer.extrude - 1)); } QColor color2 = QColor::fromRgba(img.pixel(crop.x(), crop.y() + crop.height() - 1)); p.setPen(color2); p.setBrush(color2); if(packer.extrude == 1) { p.drawPoint(QPoint(pos.x(), pos.y() + crop.height() + packer.extrude)); } else { p.drawRect(QRect(pos.x(), pos.y() + crop.height() + packer.extrude, packer.extrude - 1, packer.extrude - 1)); } QColor color3 = QColor::fromRgba(img.pixel(crop.x() + crop.width() - 1, crop.y())); p.setPen(color3); p.setBrush(color3); if(packer.extrude == 1) { p.drawPoint(QPoint(pos.x() + crop.width() + packer.extrude, pos.y())); } else { p.drawRect(QRect(pos.x() + crop.width() + packer.extrude, pos.y(), packer.extrude - 1, packer.extrude - 1)); } QColor color4 = QColor::fromRgba(img.pixel(crop.x() + crop.width() - 1, crop.y() + crop.height() - 1)); p.setPen(color4); p.setBrush(color4); if(packer.extrude == 1) { p.drawPoint(QPoint(pos.x() + crop.width() + packer.extrude, pos.y() + crop.height() + packer.extrude)); } else { p.drawRect(QRect(pos.x() + crop.width() + packer.extrude, pos.y() + crop.height() + packer.extrude, packer.extrude - 1, packer.extrude - 1)); } p.drawImage(QRect(pos.x(), pos.y() + packer.extrude, packer.extrude, crop.height()), img, QRect(crop.x(), crop.y(), 1, crop.height())); p.drawImage(QRect(pos.x() + crop.width() + packer.extrude, pos.y() + packer.extrude, packer.extrude, crop.height()), img, QRect(crop.x() + crop.width() - 1, crop.y(), 1, crop.height())); p.drawImage(QRect(pos.x() + packer.extrude, pos.y(), crop.width(), packer.extrude), img, QRect(crop.x(), crop.y(), crop.width(), 1)); p.drawImage(QRect(pos.x() + packer.extrude, pos.y() + crop.height() + packer.extrude, crop.width(), packer.extrude), img, QRect(crop.x(), crop.y() + crop.height() - 1, crop.width(), 1)); p.drawImage(pos.x() + packer.extrude, pos.y() + packer.extrude, img, crop.x(), crop.y(), crop.width(), crop.height()); } else { p.drawImage(pos.x(), pos.y(), img, crop.x(), crop.y(), crop.width(), crop.height()); } } } qint64 area = 0; for(int i = 0; i < textures.count(); i++) { area += textures.at(i).width() * textures.at(i).height(); } float percent = (((float)packer.area / (float)area) * 100.0f); // float percent2 = (float)(((float)packer.neededArea / (float)area) * 100.0f ); printf("Atlas generated. %f%% filled, %d images missed, %d merged, %d KB\n", percent, packer.missingImages, packer.mergedImages, (int)((area * 4) / 1024)); // const char * format = qPrintable(outFormat); for(int i = 0; i < textures.count(); i++) { QString imgdirFile; imgdirFile = outDir; imgdirFile += QDir::separator(); imgdirFile += outFile; if(textures.count() > 1) { imgdirFile += QString("_") + QString::number(i + 1); } imgdirFile += "."; imgdirFile += outFormat.toLower(); textures.at(i).save(imgdirFile); } return 0; } QTranslator myTranslator; myTranslator.load("tile_" + QLocale::system().name(), "qm"); a.installTranslator(&myTranslator); MainWindow w; w.show(); return a.exec(); }