Перейти к содержанию

Перекраска персонажей


Рекомендуемые сообщения

Опубликовано

Sx2Tbs0Lwbxzhvd_1772181563.webp Периодически вижу, что кто-то перекрашивает персонажей, и судя по всему это труд не маленький. Но почему то не кто не пытается это дело автоматизировать. Я долго думал над этим вопросом, даже был план сделать некий генератор. Но объём работы большой, а мне хотелось бы маленький эксперемет, чтобы в течение вечера уже видеть результат. И я решил, что надо сделать просто перекраску указаного 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];

 

Можно реализовать, просмотр в текстовом режиме, я с этого начал

Ay8oPZlFODExyNu_1772182272.webp

 

Да, тут на скрине видно, красным выделено - это тёмно-тёмно зелёный цвет. По идее его не должно тут быть,я бы его заменил на чёрный 207, который есть рядом. Но это вопрос открытый, тут уже будет не перекраска, а исправление картинки. Но с этим труднее, в плане автоматизации, можно удалить мелкую, но важную деталь.

Опубликовано

Я не реализовал до конца. Один кадр - это примерно, равносильно чтению файла с диска. Что прочитать, что прочитать и покрасить. Там нет ничего что могло бы тормозить, весь файл читаем в память, дальше пробегаем по кадрам и заменяем цвета, на нужные из палитры. Думаю, если если все файлы персонажа по очереди перекрашивать (скриптом), то за несколько минут будет всё готово. Но я еще не сделал, пробежку по всем кадрам. Пока только эксперимент. Я всегда всё делаю на малой части, все попытки сразу делать полный вариант - приводят к краху ))

Главная проблема, это подобрать нужные цвета для палитр. Я оттолкнулся, от того, что в базовой картинке 16 оттенков цвета. Можно предположить, что чисто белый и чёрный, это еще два оттенка цвета, на самых границах диапазона. Но их мы не меняем. К сожалению, чистых цветов на 16 оттенков, мало в палитре Фаллоута.

Красный, Телесный, Оранжевый, Серый (тут можно почти 20 оттенков собрать, даже избыточно), Бледно синий, и Зелёный можно собрать. Так же коричневый можно сделать, используя телесный цвет в качестве очень светлых тонов. Так же можно поступить с жёлтым. Остальное всё очень малым количеством цветов представлено, но можно попробовать дизеринг - тогда в теории выйдет десятка три разных цветов.

new-NABLUEAA.jpg

Вот попробовал телесную палитру (светло коричневый на монахе выходит, на жителях убежища еще темнее будет). Кстати по этому принципу, скорее всего можно броню из братства стали в золотую переделать, если конечно. оттенков жёлтого хватит. и Зелёные пиксели не испортят всё дело, там почему то попадаются зелёные пиксели - видимо Братство использовало медь, для покрытия и она окислилась, местами )))

Опубликовано

У меня отображается нормально. Ладно пофиг, там коричневый монах, я уже стёр оригинал ))

 new_NABLUEAA.png

Если вдруг не видно, вот для оранжевого монаха https://fotohosting.pro/i/new-NABLUEAA.ljCIH

Пока пять палитр сделал, пытаюсь насобирать для розового цвета цвет, но видимо это будет почти тот же красный, с заменой самых светлых оттенков...

Опубликовано

Где не хватает оттенков, решил чуток схитрить, дублируя цвета:

const uint8_t yellowColor[16] =
{   220, 56, 56, 57, 57, 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 67};

 По итогу 11-12 цветов получится, ну и на монахе и жители убежища, по разному цвет себя проявит, на жители чуть темнее будет.

Качество конечно похуже получается...

Опубликовано

0b9d1ed6c7b2028cda152fcfc4de82c4.png

Получилось, 14 цветов, тут 12. Но последний сиреневый - на мой взгляд не очень, он тут не влез. Я еще на днях подумаю, над этим вопросом и что нибудь переделаю... Ну а потом, уже прикручу полную перекраску всего файла.

Опубликовано

Плавности палитр не хватает, маловато цветов, выжал 15 - но результат далёк от идеала. На монахах еще ничего, а на девушках уже не очень, когда более светлые цвета в большинстве.

d00d66b73c94eac6f42bc49428409760.png

 

Спойлер
#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;
}

 

 

Опубликовано

Сделал мини утилиту (так как тут вроде большинство под виндой, то сделал exe), Скачать файл (200kb+)

Перекраска синего цвета, с учетом, затемнения, как то так. В общем синих персонажей, делает другого цвета.

 

Применение:

  • Файл.frm [номер цвета от 0 до 14]
  • Файл.frm -d [номер цвета от 0 до 14]           Цвет будет темнее
  • Файл.frm  -l [номер цвета от 0 до 14]           Цвет будет светлее
  • Файл.frm                                                         Будет перекрашено в нулевой цвет, серый

Тестировал из под Wine. Цвета примерно так идут (но всё зависит от картинки):

  1. Красный
  2. Ярко-красный
  3. Коричневый
  4. Оранжевый, но больше на светло коричневый в итоге похоже
  5. Синий (почти тот же что и у исходной картинки)
  6. Яшма (что-то вроде сухой тёмной глины)
  7. Зелёный, темный
  8. Желтый как бы, но из-за малого количества цветов, тоже ближе к очень светло коричневому
  9. Красно-коричневый
  10. Еще один вариант красного цвета
  11. Бледно зелёный
  12. Что-то еще близкое к коричнево-оранжевому ))
  13. Очень тёмный красный цвет.
  14. Сиреневый (очень мало цветов, что вышло, то вышло)

ДА, нулевой это светло серый. Ну и не забываем, всё зависит от цветов в исходной картинке, чем они темнее, тем темнее будет результат

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...