stratego Опубликовано 27 февраля Опубликовано 27 февраля Периодически вижу, что кто-то перекрашивает персонажей, и судя по всему это труд не маленький. Но почему то не кто не пытается это дело автоматизировать. Я долго думал над этим вопросом, даже был план сделать некий генератор. Но объём работы большой, а мне хотелось бы маленький эксперемет, чтобы в течение вечера уже видеть результат. И я решил, что надо сделать просто перекраску указаного FRM файла. Понятно, что много цветных персонажей - не переделать автоматически. Но вот жителей убежища - запросто, вчера сел за код и сделал, для теста перекраску первого кадра. Алгоритм заменяет все оттенки синего, на красный (пока только на красный), там еще надо настройки добавить, чтобы можно было темнее-светлее сделать. А потом я вспомнил, что есть вышибалы, монах и еще полицейские с синими одеждами. Там тоже всё сработало. const uint8_t redColor[16] = { 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 181 }; .... //Загружаем, и всё такое // Сам алгоритм, в цикле прогоняем картинку и заменяем нужные цвета size_t index = 74 + x + y * wFrame; uint8_t col = buffer[index]; if((col > 31 && col < 48)) buffer[index] = redColor[col - 32]; if((col > 100 && col < 112)) buffer[index] = redColor[col - 101 + 5]; if((col == 113)) buffer[index] = redColor[9]; if((col == 115)) buffer[index] = redColor[8]; if((col == 116)) buffer[index] = redColor[11]; Можно реализовать, просмотр в текстовом режиме, я с этого начал Да, тут на скрине видно, красным выделено - это тёмно-тёмно зелёный цвет. По идее его не должно тут быть,я бы его заменил на чёрный 207, который есть рядом. Но это вопрос открытый, тут уже будет не перекраска, а исправление картинки. Но с этим труднее, в плане автоматизации, можно удалить мелкую, но важную деталь. 1
Генерал Максон Опубликовано 27 февраля Опубликовано 27 февраля Сколько приблизительно по времени занимает перекраска персонажа? Egon Spengler - Classic Games (форум)
stratego Опубликовано 27 февраля Автор Опубликовано 27 февраля Я не реализовал до конца. Один кадр - это примерно, равносильно чтению файла с диска. Что прочитать, что прочитать и покрасить. Там нет ничего что могло бы тормозить, весь файл читаем в память, дальше пробегаем по кадрам и заменяем цвета, на нужные из палитры. Думаю, если если все файлы персонажа по очереди перекрашивать (скриптом), то за несколько минут будет всё готово. Но я еще не сделал, пробежку по всем кадрам. Пока только эксперимент. Я всегда всё делаю на малой части, все попытки сразу делать полный вариант - приводят к краху )) Главная проблема, это подобрать нужные цвета для палитр. Я оттолкнулся, от того, что в базовой картинке 16 оттенков цвета. Можно предположить, что чисто белый и чёрный, это еще два оттенка цвета, на самых границах диапазона. Но их мы не меняем. К сожалению, чистых цветов на 16 оттенков, мало в палитре Фаллоута. Красный, Телесный, Оранжевый, Серый (тут можно почти 20 оттенков собрать, даже избыточно), Бледно синий, и Зелёный можно собрать. Так же коричневый можно сделать, используя телесный цвет в качестве очень светлых тонов. Так же можно поступить с жёлтым. Остальное всё очень малым количеством цветов представлено, но можно попробовать дизеринг - тогда в теории выйдет десятка три разных цветов. Вот попробовал телесную палитру (светло коричневый на монахе выходит, на жителях убежища еще темнее будет). Кстати по этому принципу, скорее всего можно броню из братства стали в золотую переделать, если конечно. оттенков жёлтого хватит. и Зелёные пиксели не испортят всё дело, там почему то попадаются зелёные пиксели - видимо Братство использовало медь, для покрытия и она окислилась, местами )))
Генерал Максон Опубликовано 27 февраля Опубликовано 27 февраля Должно быть занимательный процесс. К слову, у Вас что-то с картинкой в сообщении не то. Egon Spengler - Classic Games (форум)
Генерал Максон Опубликовано 27 февраля Опубликовано 27 февраля 3 часа назад, stratego сказал: С которой? Перед мои сообщением. Два абзаца текста, между ними подобие ссылки: "new-NABLUEAA.jpg" Egon Spengler - Classic Games (форум)
stratego Опубликовано 27 февраля Автор Опубликовано 27 февраля У меня отображается нормально. Ладно пофиг, там коричневый монах, я уже стёр оригинал )) Если вдруг не видно, вот для оранжевого монаха https://fotohosting.pro/i/new-NABLUEAA.ljCIH Пока пять палитр сделал, пытаюсь насобирать для розового цвета цвет, но видимо это будет почти тот же красный, с заменой самых светлых оттенков...
stratego Опубликовано 27 февраля Автор Опубликовано 27 февраля Где не хватает оттенков, решил чуток схитрить, дублируя цвета: const uint8_t yellowColor[16] = { 220, 56, 56, 57, 57, 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 67}; По итогу 11-12 цветов получится, ну и на монахе и жители убежища, по разному цвет себя проявит, на жители чуть темнее будет. Качество конечно похуже получается...
stratego Опубликовано 27 февраля Автор Опубликовано 27 февраля Получилось, 14 цветов, тут 12. Но последний сиреневый - на мой взгляд не очень, он тут не влез. Я еще на днях подумаю, над этим вопросом и что нибудь переделаю... Ну а потом, уже прикручу полную перекраску всего файла. 1
stratego Опубликовано 28 февраля Автор Опубликовано 28 февраля Плавности палитр не хватает, маловато цветов, выжал 15 - но результат далёк от идеала. На монахах еще ничего, а на девушках уже не очень, когда более светлые цвета в большинстве. Спойлер #include <iostream> #include <fstream> //#include <iomanip> #define HTONS(n) (buffer[n+1] | (uint16_t(buffer[n]) << 8)) #define HTONL(n) (buffer[n+3] | (buffer[n + 2]) << 8 | (buffer[n + 1]) << 16 | (buffer[n]) << 24) static constexpr uint8_t Colors[15][16] = { { 1, 2, 3, 4, 5, 112, 6, 211, 7, 210, 8, 9, 10, 11, 12, 14 }, //серый { 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 181 }, // Красный { 220, 16, 17, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138 }, // Ярко красный { 169, 156, 170, 171, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168 }, // Коричневый { 169, 156, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155 }, // Оранжевый { 220, 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45}, // Синий { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, //Яшма { 56, 69, 70, 71, 72, 87, 73, 88, 74, 91, 92, 75, 93, 94, 95, 96}, // Пихтовый, непонятно зелёный { 220, 56, 56, 57, 57, 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 67}, // жёлтый { 220, 182, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195}, // красно-коричневый { 220, 169, 156, 170, 157, 158, 159, 173, 174, 175, 176, 177, 178, 179, 180, 181}, // красно-коричневый, еще один { 56, 69, 70, 70, 196, 215, 216, 217, 198, 197, 200, 219, 73, 74, 75, 96}, // светло-зелёный { 142, 143, 185, 186, 187, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154 }, // Светло-Оранжевый { 220, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 195}, // { 220, 16, 17, 126, 127, 48, 49, 50, 50, 51, 51, 52, 52, 53, 54, 55} // Сиреневый }; const uint8_t *arrayColor; using namespace std; int main(int argc, char** argv) { if(argc < 1) return 0; string fileNameIn = argv[1]; string fileNameOut = string("new_") + fileNameIn; ifstream fileIn(fileNameIn, ios::binary); if(!fileIn.is_open()) { cout << "\033[38;2;255;0;0m < no file " << fileNameIn << " >\033[0m" << endl; return 0; } // Получаем размер файла fileIn.seekg(0, ios::end); size_t fileSize = fileIn.tellg(); cout << "file size: " << fileSize << endl; fileIn.seekg(0, ios::beg); // uint8_t *buffer = new uint8_t[fileSize]; fileIn.read((char*)buffer, fileSize); fileIn.close(); // uint16_t countFrames = HTONS(8); cout << countFrames << endl; uint32_t offsetFrames[6]; for(uint32_t i = 0; i < 6; i++) { offsetFrames[i] = HTONL(34 + i * 4) + 62; cout << i << " frame offset: " << offsetFrames[i] << endl; } uint32_t iPal = 0; // Номер палитры for(uint32_t i = 0; i < 6; i++) { uint32_t offset = offsetFrames[i]; for(uint16_t f = 0; f < countFrames; f++) { uint16_t wFrame = HTONS(offset); cout << wFrame << endl; offset += 2; uint16_t hFrame = HTONS(offset); cout << hFrame << endl; offset += 10; //cout << "Colors: " << endl; arrayColor = Colors[iPal++]; for(uint16_t y = 0; y < hFrame; y++) { for(uint16_t x = 0; x < wFrame; x++) { size_t index = offset++; uint8_t col = buffer[index]; if((col > 31 && col < 48)) buffer[index] = arrayColor[col - 32]; if((col > 100 && col < 112)) buffer[index] = arrayColor[col - 101 + 5]; if((col == 113)) buffer[index] = arrayColor[9]; if((col == 115)) buffer[index] = arrayColor[8]; if((col == 116)) buffer[index] = arrayColor[11]; } } // End Frame (конец перезаписи одного кадра) iPal = iPal%15; // Исправляем значение, если ушли дальше количества палитр } //Конец полоски кадров (одно направление) } ofstream fileOut(fileNameOut, ios::binary); fileOut.write((char*)buffer, fileSize); fileOut.close(); return 0; }
stratego Опубликовано Понедельник в 07:32 Автор Опубликовано Понедельник в 07:32 Сделал мини утилиту (так как тут вроде большинство под виндой, то сделал exe), Скачать файл (200kb+) Перекраска синего цвета, с учетом, затемнения, как то так. В общем синих персонажей, делает другого цвета. Применение: Файл.frm [номер цвета от 0 до 14] Файл.frm -d [номер цвета от 0 до 14] Цвет будет темнее Файл.frm -l [номер цвета от 0 до 14] Цвет будет светлее Файл.frm Будет перекрашено в нулевой цвет, серый Тестировал из под Wine. Цвета примерно так идут (но всё зависит от картинки): Красный Ярко-красный Коричневый Оранжевый, но больше на светло коричневый в итоге похоже Синий (почти тот же что и у исходной картинки) Яшма (что-то вроде сухой тёмной глины) Зелёный, темный Желтый как бы, но из-за малого количества цветов, тоже ближе к очень светло коричневому Красно-коричневый Еще один вариант красного цвета Бледно зелёный Что-то еще близкое к коричнево-оранжевому )) Очень тёмный красный цвет. Сиреневый (очень мало цветов, что вышло, то вышло) ДА, нулевой это светло серый. Ну и не забываем, всё зависит от цветов в исходной картинке, чем они темнее, тем темнее будет результат
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти