Closed Sigura closed 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).
@Sigura Думаю на Amazfit X структура циферблата аналогично с GTR2. Я пытался разобраться в циферблатах от GTR2, но у меня ничего не вышло. Надеюсь у тебя это получится.
@Sigura Думаю на Amazfit X структура циферблата аналогично с GTR2. Я пытался разобраться в циферблатах от GTR2, но у меня ничего не вышло. Надеюсь у тебя это получится.
Спасибо за подробный ответ!
Я полагаю, что ты прав. Только теперь я даже не надеюсь что что-то получится, ты явно на этом "собаку съел", но я попробую на выходных с распаковкой простого циферблата.
ps: про язык, я просто не хотел чтоб на качество общения поимела влияние политика и прочие глупости, короче, рад слышать.
По твоей ссылке утилита для распаковки циферблатов от Bip. Я ее пытался переделать под GTR, но она у меня работала не стабильно (если хочешь пришлю что получилось).
если не лень, то пришли, пожалуйста. телеграмм: Sigura256
https://github.com/SashaCX75/Amazfit/tree/developer Запускается из WatchFace_PackUnpack Я делал упор на извлечение ресурсов из циферблата. Поэтому часть ошибок отключил, возможно что-то испортил. Но на GTR2 структура циферблата отличается от GTR. Думаю основная проблема будет в расшифровке bin файла. И не забывай что bin файл дополнительно может быть сжат.
Если можешь пришли несколько циферблатов Amazfit X. Ради интереса попробую сравнить их структуру с GTR2 и GTR
Спасибо!
я уже что-то попробовал, там пробелмы уже с заголовка начинаются с чтения размера параметров. Ожидается что они будут с 36 места, а там 255, 255, ...
Мой план:
я в этом треде добавил один из дефолтных: https://myamazfit.ru/threads/bip-amazfit-bip-tools.109/page-3#post-51615
прямая ссылка: https://myamazfit.ru/attachments/0ca640495eafbca80926b316f4f94be9-bin-zip.29918/
По умолчанию в часах есть сильно более продвинтая версия циферблата, в нем есть "панельки", которые можно менять, то есть "циферблаты" внутри циферблата. Пока не придумал как достать тот который по умолчанию.
Могу тебя обрадовать, структура циферблата похожа на GTR. Распаковать его получилось. Думаю с упаковкой тоже особых проблем не будет, нfдо только чтобы паковщик вставлял нужный ID в binфайл. Если знаком с питоном, то лучше ковыряй эту утилиту.
Ресурсы из распакованого циферблата 0ca640495eafbca80926b316f4f94be9.zip Стандартным способом не распаковывается, потому что есть один параметр которого нет в GTR. Предполагаю это PAI (или значение под человечков в левом верхнем углу, не знаю что это такое). Поищи циферблат на котором нет этих параметров и поэксперементируй с ним.
Попробовал разобрать и собрать циферблат. Теоретически получилось, но проверить не могу. Единственная разница фоновая картинка в фоновом циферблате была 16 bit/pixsel а в новом 32 bit/pixsel. Не знаю насколько это критично. Если не боишься экспериментировать, то можешь попробовать поставить. test_packed.zip
перименовал test_packed.zip
в 0ca640495eafbca80926b316f4f94be9.bin
залил на андроид /Android/data/com.huami.watch.hmwatchmanager/files/watch_skin_local/
отправил на часы, после отправки получил Failed to Sync
(
любопытно, что когда распаковал в 1.7mb bin, то с телефона он не захотел отправляться, сразу ошибку написал.
Помойму я отправил не ту версию. Попробуй эту. Архив распаковывать. test_packed.zip
симптомы такие же к сожалению (
распакованный 0ca640495eafbca80926b316f4f94be9.bin Zepp даже не пытается лить в часы.
а ты переписывал функцию чтения картинок для 16bit?
Чтение переписал а запись оставил 32bit. Просто в первом посте ошибочно выложил bin файл запакованный под мои GTR. Может фоновая картинка должна быть именно 16bit, но даже если это так, это вряд ли проверяется до заливки циферблата в часы и его распаковки. Может есть ограничение на размер файла, но на остальных моделей при превышении размера циферблат заливается но не ставится или не все элементы отображаются. Других предположений что у меня нет. В общем распаковать получается, а запаковать пока не получается.
я пока не понимаю как считать ту картинку, в общем 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
извиняюсь за говнокод, я нуб в питоне, не хотел слишком много менять,
к чему мои потуги - я думаю, что если научиться читать, то и записать можно будет без хлопот,
тогда всё должно быть ок, но если нет, то буду искать решение дальше
я попробовал отправить оригинальный распакованный циферблат и он залился.
похоже Zepp проверяет расспакованные перед отправкой, а запакованные льет как есть.
update: да, распакованный -> не сжатый. довёл чтение до ума, надо сохранять тоже 16 бит и их же упаковывать.
Не понял что значит "распакованный циферблат залился". Распакованный циферблат это набор картинок и они не могут залиться. Может ты имел ввиду сжатый и не сжатый bin файл?
AmazFit_WatchfaceEditor(Python)_beta.zip Это то, что получилось у меня. Распаковывает вроде нормально. Запаковка тоже вроде проходит, но почему не работаю я не знаю С питоном не знаком, правил его как мог.
Еще один вариант на C# но работает хуже. При наличии некоторых параметров в циферблате вообще собирает bin файл неправильно.
Исходники есть у меня в репозитории.
Слегка поправил скрипт для распаковки py_amazfit_tools_beta.zip
я попробовал отправить оригинальный распакованный циферблат и он залился.
да, конечно, я имел в виду не сжатый.
попробовал сделать фоновую картинку в 16 bit формате packed.zip
Если это не помогло пришли еще несколько циферблатов для теста. В заголовке bin файла заметил отличие от файлов для GTR. Скорее всего из за этого и не ставится. Если это статичные данные (часть заголовка для проверки совместимости с моделью часов) то это можно будет исправит. А если это динамичные данные, то сложно будет вычислить от чего они зависят.
добавил ещё 3 https://myamazfit.ru/attachments/faces-zip.29936/
из найденных отличий добавил в hackBuffer
:
53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x
попробовал сделать фоновую картинку в 16 bit формате packed.zip
залился и заработал но без бекграунда, что уже очень круто, мне этого не удалось, можешь код парсера/упаковщика залить куда нибудь?
можно было бы на этом тестировать: 0ca640495eafbca80926b316f4f94be9_first.bin.zip
на всякий случай ещё раз обращаю твоё внимание на не обычную упаковку 16битки, тут код https://github.com/SashaCX75/AmazFit_Watchface_Editor/issues/36#issuecomment-727198214, где _step == 2
из найденных отличий добавил в
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
Для теста пересобрал твои циферблаты, Проверь работают или нет. a1bc59d902b43a7549c481e7e723f91f.zip b185ad5b972683769206cc13b39bc42e.zip 9d2204203f5e206956008d4ef8799e06.zip
И еще, что это за параметр рядом с которым иконка человечка?
из найденных отличий добавил в
hackBuffer
:53 : [0x35, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4b, 0x9a], # x
Подскажи почему номер 53. Я не понял нумерации строк. Почему 53 AmazfitX а 47 для gtr 47. Откуда взялись эти цифры. Я например поставил 51 для AmazfitX и все вроде работает.
там же отдельный слварь, можно и 51 поставить, я на всякий случай написал, если кто ещё разбираться будет.
тем не менее у меня заработал мой циферблат, всё что сделал по сути - убрал размер (картинки для шагов): 0ca640495eafbca80926b316f4f94be9.zip
погода там не показывается корректно, статусы тоже бессмысленны (bt не отключить, как я понял), нашел их стандартный циферблат с погодой, там тоже погода не работает 66dfb121feeb5faf8b9ac3f71262ff2c.bin.zip
update: погода как-то заработала, но ожидать стабильной работы не приходиться
И еще, что это за параметр рядом с которым иконка человечка?
я хз это Stand, ещё не разбирался, оставил, просто для симметрии на экране
То есть можно считать, что все работает? Осталось только написать процедуру конвертации фоновой картинки в формат 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 а наличия связи с телефоном.
То есть можно считать, что все работает? Осталось только написать процедуру конвертации фоновой картинки в формат 16 bit.
да, это было бы круто, потому что размер стал архи критичен.
Думаю 53 логичней (53 dec = 0x35 hex)
+1
С погодой почти на всех моделях проблемы.
да, но! в самих X есть циферблат по умолчанию, там показывается погода аж на 3 дня. И работает чудно. Я пока не понял как этот циферблат оттуда вытащить, в общем списке Zepp его нет.
Это не значек включения Bluetooth а наличия связи с телефоном.
Спасибо!
https://github.com/SashaCX75/py_amazfit_tools/tree/AmazfitX Это сткрипт на питоне с которым я эксперементирую с AmazfitX. Думаю обсуждение лучше продолжить в той ветке. Вроде осталось только в процедуре def writeImage16(self): прописать алгоритм сжатия 16битного изображения
Вроде разобрался с фоном. Проверяй test.zip Цветные полосы посредине это не глюк, они для проверки цветности.
Вроде разобрался с фоном. Проверяй
работает, даёшь 16bit! )
тогда можно будет и превью норм сделать
Обновил в репозитории. Тестируй. Еще вопрос. Углы на экране ровные, Не закругленные как на GTS?
Не закругленные как на GTS?
не заметил такого
I will glad to add Amazfit X support.
But got an error on the build. It looks like
WatchFace.Parser
missed:could you please add it to the source?
Or I miss something?