SashaCX75 / AmazFit_Watchface_Editor

Графический редактор для работы с циферблатами Amazefit
14 stars 11 forks source link

[build] [error] WatchFace.Parser does not exist. #36

Closed Sigura closed 4 years ago

Sigura commented 4 years ago

I will glad to add Amazfit X support.

But got an error on the build. It looks like WatchFace.Parser missed:

 The referenced project '..\..\Projects\Amazfit\WatchFace.Parser\WatchFace.Parser.csproj' does not exist.

could you please add it to the source?

Or I miss something?

Sigura commented 4 years ago

is it?

https://bitbucket.org/valeronm/amazfitbiptools/src/master/

SashaCX75 commented 4 years ago

@Sigura Судя по твоему имени и местоположению наверно будет проще общаться на русском. Собирать надо проект AmazFit_Watchface_Editor. Остальные проекты устарели и были объединены в один. Для распаковки циферблатов используются две внешние утилиты https://github.com/amazfitbip/py_amazfit_tools/releases/tag/v0.2-beta https://github.com/amazfitbip/resunpacker_qzip Думаю будет проще если ты скачаешь готовый проект например отсюда и скопируешь необходимые папки в папку с исполняемым файлом.

По твоей ссылке утилита для распаковки циферблатов от Bip. Я ее пытался переделать под GTR, но она у меня работала не стабильно (если хочешь пришлю что получилось).

Judging by your name and location, it will probably be easier to communicate in Russian. You need to collect the AmazFit_Watchface_Editor project. The rest of the projects are outdated and have been merged into one. Two external utilities are used to unpack the dials https://github.com/amazfitbip/py_amazfit_tools/releases/tag/v0.2-beta https://github.com/amazfitbip/resunpacker_qzip I think it will be easier if you download the finished project [for example from here] (https://github.com/SashaCX75/AmazFit_Watchface_Editor/releases/tag/v9.0-beta) and copy the necessary folders to the folder with the executable file.

Utility for unpacking dials from Bip is at your link. I tried to remake it for GTR, but it did not work for me stably (if you want to send what happened).

SashaCX75 commented 4 years ago

@Sigura Думаю на Amazfit X структура циферблата аналогично с GTR2. Я пытался разобраться в циферблатах от GTR2, но у меня ничего не вышло. Надеюсь у тебя это получится.

Sigura commented 4 years ago

@Sigura Думаю на Amazfit X структура циферблата аналогично с GTR2. Я пытался разобраться в циферблатах от GTR2, но у меня ничего не вышло. Надеюсь у тебя это получится.

Спасибо за подробный ответ!

Я полагаю, что ты прав. Только теперь я даже не надеюсь что что-то получится, ты явно на этом "собаку съел", но я попробую на выходных с распаковкой простого циферблата.

ps: про язык, я просто не хотел чтоб на качество общения поимела влияние политика и прочие глупости, короче, рад слышать.

Sigura commented 4 years ago

По твоей ссылке утилита для распаковки циферблатов от Bip. Я ее пытался переделать под GTR, но она у меня работала не стабильно (если хочешь пришлю что получилось).

если не лень, то пришли, пожалуйста. телеграмм: Sigura256

SashaCX75 commented 4 years ago

https://github.com/SashaCX75/Amazfit/tree/developer Запускается из WatchFace_PackUnpack Я делал упор на извлечение ресурсов из циферблата. Поэтому часть ошибок отключил, возможно что-то испортил. Но на GTR2 структура циферблата отличается от GTR. Думаю основная проблема будет в расшифровке bin файла. И не забывай что bin файл дополнительно может быть сжат.

SashaCX75 commented 4 years ago

Если можешь пришли несколько циферблатов Amazfit X. Ради интереса попробую сравнить их структуру с GTR2 и GTR

Sigura commented 4 years ago

Спасибо!

я уже что-то попробовал, там пробелмы уже с заголовка начинаются с чтения размера параметров. Ожидается что они будут с 36 места, а там 255, 255, ...

Мой план:

я в этом треде добавил один из дефолтных: https://myamazfit.ru/threads/bip-amazfit-bip-tools.109/page-3#post-51615

прямая ссылка: https://myamazfit.ru/attachments/0ca640495eafbca80926b316f4f94be9-bin-zip.29918/

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

SashaCX75 commented 4 years ago

Могу тебя обрадовать, структура циферблата похожа на GTR. Распаковать его получилось. Думаю с упаковкой тоже особых проблем не будет, нfдо только чтобы паковщик вставлял нужный ID в binфайл. Если знаком с питоном, то лучше ковыряй эту утилиту.

Ресурсы из распакованого циферблата 0ca640495eafbca80926b316f4f94be9.zip Стандартным способом не распаковывается, потому что есть один параметр которого нет в GTR. Предполагаю это PAI (или значение под человечков в левом верхнем углу, не знаю что это такое). Поищи циферблат на котором нет этих параметров и поэксперементируй с ним.

SashaCX75 commented 4 years ago

Попробовал разобрать и собрать циферблат. Теоретически получилось, но проверить не могу. Единственная разница фоновая картинка в фоновом циферблате была 16 bit/pixsel а в новом 32 bit/pixsel. Не знаю насколько это критично. Если не боишься экспериментировать, то можешь попробовать поставить. test_packed.zip

Sigura commented 4 years ago

перименовал test_packed.zip в 0ca640495eafbca80926b316f4f94be9.bin залил на андроид /Android/data/com.huami.watch.hmwatchmanager/files/watch_skin_local/ отправил на часы, после отправки получил Failed to Sync (

любопытно, что когда распаковал в 1.7mb bin, то с телефона он не захотел отправляться, сразу ошибку написал.

SashaCX75 commented 4 years ago

Помойму я отправил не ту версию. Попробуй эту. Архив распаковывать. test_packed.zip

Sigura commented 4 years ago

симптомы такие же к сожалению (

распакованный 0ca640495eafbca80926b316f4f94be9.bin Zepp даже не пытается лить в часы.

а ты переписывал функцию чтения картинок для 16bit?

SashaCX75 commented 4 years ago

Чтение переписал а запись оставил 32bit. Просто в первом посте ошибочно выложил bin файл запакованный под мои GTR. Может фоновая картинка должна быть именно 16bit, но даже если это так, это вряд ли проверяется до заливки циферблата в часы и его распаковки. Может есть ограничение на размер файла, но на остальных моделей при превышении размера циферблат заливается но не ставится или не все элементы отображаются. Других предположений что у меня нет. В общем распаковать получается, а запаковать пока не получается.

Sigura commented 4 years ago

я пока не понимаю как считать ту картинку, в общем readImage написан верно, попробовал читать по 5 битов на цвет. по спецификации 16 bit только для grayscale, но она там точно цветная.

записано примерно так:

11001001 00000000
11g]0 [01001b] [00000r] [000

рабочий вариант:

    def readImage(self):
        image = Image.new('RGBA', (self._width, self._height))
        for y in range(self._height):
            rowBytes = self._reader.read(self._rowLengthInBytes)
            for x in range(self._width):
                try:
                    if self._step > 2:
                        b = rowBytes[x * self._step]
                        g = rowBytes[x * self._step + 1]
                        r = rowBytes[x * self._step + 2]

                        if self._step == 4:
                            a = rowBytes[x * self._step + 3]
                        else:
                            a = 255
                    elif self._step == 2:
                        b = int(((rowBytes[x * self._step] - ((rowBytes[x * self._step] >> 5) << 5))) * 255 / 31 )
                        r = int((rowBytes[x * self._step + 1] >> 3) * 255 / 31 )
                        g = int(((((rowBytes[x * self._step + 1] - ((rowBytes[x * self._step + 1] >> 3) << 3)) << 2) + (rowBytes[x * self._step] >> 6) )) * 255 / 31 )
                        a = 255
                    elif self._step == 1:
                        b = rowBytes[x * self._step]
                        r = b
                        g = b
                        a = 255

                    color = resources.image.color.Color.fromArgb(a, r, g, b)
                    image.putpixel((x,y), color)
                except Exception as e:
                    logging.info(f"y:{y}, x: {x * self._step}, length: {len(rowBytes)}, b: {b}, g: {g}, r: {r}, e: {e}")
        return image
Sigura commented 4 years ago

извиняюсь за говнокод, я нуб в питоне, не хотел слишком много менять,

к чему мои потуги - я думаю, что если научиться читать, то и записать можно будет без хлопот,

тогда всё должно быть ок, но если нет, то буду искать решение дальше

Sigura commented 4 years ago

я попробовал отправить оригинальный распакованный циферблат и он залился.

похоже Zepp проверяет расспакованные перед отправкой, а запакованные льет как есть.

update: да, распакованный -> не сжатый. довёл чтение до ума, надо сохранять тоже 16 бит и их же упаковывать.

SashaCX75 commented 4 years ago

Не понял что значит "распакованный циферблат залился". Распакованный циферблат это набор картинок и они не могут залиться. Может ты имел ввиду сжатый и не сжатый bin файл?

SashaCX75 commented 4 years ago

AmazFit_WatchfaceEditor(Python)_beta.zip Это то, что получилось у меня. Распаковывает вроде нормально. Запаковка тоже вроде проходит, но почему не работаю я не знаю С питоном не знаком, правил его как мог.

SashaCX75 commented 4 years ago

WatchFace_PackUnpack.zip

Еще один вариант на C# но работает хуже. При наличии некоторых параметров в циферблате вообще собирает bin файл неправильно.

Исходники есть у меня в репозитории.

SashaCX75 commented 4 years ago

Слегка поправил скрипт для распаковки py_amazfit_tools_beta.zip

Sigura commented 4 years ago

я попробовал отправить оригинальный распакованный циферблат и он залился.

да, конечно, я имел в виду не сжатый.

SashaCX75 commented 4 years ago

попробовал сделать фоновую картинку в 16 bit формате packed.zip

Если это не помогло пришли еще несколько циферблатов для теста. В заголовке bin файла заметил отличие от файлов для GTR. Скорее всего из за этого и не ставится. Если это статичные данные (часть заголовка для проверки совместимости с моделью часов) то это можно будет исправит. А если это динамичные данные, то сложно будет вычислить от чего они зависят.

Sigura commented 4 years ago

добавил ещё 3 https://myamazfit.ru/attachments/faces-zip.29936/

из найденных отличий добавил в hackBuffer:

    53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x
Sigura commented 4 years ago

попробовал сделать фоновую картинку в 16 bit формате packed.zip

залился и заработал но без бекграунда, что уже очень круто, мне этого не удалось, можешь код парсера/упаковщика залить куда нибудь?

можно было бы на этом тестировать: 0ca640495eafbca80926b316f4f94be9_first.bin.zip

Sigura commented 4 years ago

на всякий случай ещё раз обращаю твоё внимание на не обычную упаковку 16битки, тут код https://github.com/SashaCX75/AmazFit_Watchface_Editor/issues/36#issuecomment-727198214, где _step == 2

SashaCX75 commented 4 years ago

из найденных отличий добавил в hackBuffer:

    53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x

Это подпись циферблата. Это первое что я поменял

залился и заработал но без бекграунда, что уже очень круто, мне этого не удалось, можешь код парсера/упаковщика залить куда нибудь?

Что заработало это хорошо. Задний фон черный потому, что пока не стал возиться с перекодировкой при запаковке и для теста просто впихнул черный фон. Сам парсер на питоне есть в архиве с редактором, который я тебе высылал и потом отдельно присылал некоторые подправленные файлы. Чуть позже на репозитории выложу подправленный код.

на всякий случай ещё раз обращаю твоё внимание на не обычную упаковку 16битки, тут код #36 (comment), где _step == 2

Это код ля распаковки циферблата. У меня вроде распаковывается нормально, поэтому менять этот код не вижу смысла Посмотри в том же файле у меня процедуру def readImage16(self):

def readImage16(self):
        image = Image.new('RGBA', (self._width, self._height))
        for y in range(self._height):
            rowBytes = self._reader.read(self._rowLengthInBytes)
            for x in range(self._width):
                firstByte = rowBytes[x * self._step];
                secondByte = rowBytes[x * self._step + 1];
                r = ((secondByte >> 3) & 0x1f) << 3;
                g = (((firstByte >> 5) & 0x7) | ((secondByte & 0x07) << 3)) << 2;
                b = (firstByte & 0x1f) << 3;
                alpha = 255
                color = resources.image.color.Color.fromArgb(alpha, r, g, b)
                image.putpixel((x,y), color)
        return image
SashaCX75 commented 4 years ago

Для теста пересобрал твои циферблаты, Проверь работают или нет. a1bc59d902b43a7549c481e7e723f91f.zip b185ad5b972683769206cc13b39bc42e.zip 9d2204203f5e206956008d4ef8799e06.zip

И еще, что это за параметр рядом с которым иконка человечка?

SashaCX75 commented 4 years ago

из найденных отличий добавил в hackBuffer:

    53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x

Подскажи почему номер 53. Я не понял нумерации строк. Почему 53 AmazfitX а 47 для gtr 47. Откуда взялись эти цифры. Я например поставил 51 для AmazfitX и все вроде работает.

Sigura commented 4 years ago

там же отдельный слварь, можно и 51 поставить, я на всякий случай написал, если кто ещё разбираться будет.

тем не менее у меня заработал мой циферблат, всё что сделал по сути - убрал размер (картинки для шагов): 0ca640495eafbca80926b316f4f94be9.zip

погода там не показывается корректно, статусы тоже бессмысленны (bt не отключить, как я понял), нашел их стандартный циферблат с погодой, там тоже погода не работает 66dfb121feeb5faf8b9ac3f71262ff2c.bin.zip

update: погода как-то заработала, но ожидать стабильной работы не приходиться

Sigura commented 4 years ago

И еще, что это за параметр рядом с которым иконка человечка?

я хз это Stand, ещё не разбирался, оставил, просто для симметрии на экране

SashaCX75 commented 4 years ago

То есть можно считать, что все работает? Осталось только написать процедуру конвертации фоновой картинки в формат 16 bit.

Давай тогда определимся 51 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # AmazfitX Или 53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x Думаю 53 логичней (53 dec = 0x35 hex)

За значение параметра спрашивал чтобы стразу правильно прописать его название. Сейчас он называется у меня Unknown15, а это не информативно.

PAI и погода там не показывается корректно

В чем именно проблема отображения? С погодой почти на всех моделях проблемы. Часто она выдает ошибку если не добавлена максимальная/минимальная температура. А на T-rex вроде вообще на некоторых прошивках она не работает.

bt не отключить, как я понял

Bluetooth на часах не отключается, но он отключается на телефоне или теряется связь если телефон далеко. Это не значек включения Bluetooth а наличия связи с телефоном.

Sigura commented 4 years ago

То есть можно считать, что все работает? Осталось только написать процедуру конвертации фоновой картинки в формат 16 bit.

да, это было бы круто, потому что размер стал архи критичен.

Думаю 53 логичней (53 dec = 0x35 hex)

+1

С погодой почти на всех моделях проблемы.

да, но! в самих X есть циферблат по умолчанию, там показывается погода аж на 3 дня. И работает чудно. Я пока не понял как этот циферблат оттуда вытащить, в общем списке Zepp его нет.

Это не значек включения Bluetooth а наличия связи с телефоном.

Спасибо!

SashaCX75 commented 4 years ago

https://github.com/SashaCX75/py_amazfit_tools/tree/AmazfitX Это сткрипт на питоне с которым я эксперементирую с AmazfitX. Думаю обсуждение лучше продолжить в той ветке. Вроде осталось только в процедуре def writeImage16(self): прописать алгоритм сжатия 16битного изображения

SashaCX75 commented 4 years ago

Вроде разобрался с фоном. Проверяй test.zip Цветные полосы посредине это не глюк, они для проверки цветности.

Sigura commented 4 years ago

Вроде разобрался с фоном. Проверяй

работает, даёшь 16bit! )

тогда можно будет и превью норм сделать

SashaCX75 commented 4 years ago

Обновил в репозитории. Тестируй. Еще вопрос. Углы на экране ровные, Не закругленные как на GTS?

Sigura commented 4 years ago

Не закругленные как на GTS?

не заметил такого