--- /dev/null
+usage: main.py [-h] [-file FILE] [-dir DIR] [-output OUTPUT]\r
+\r
+options:\r
+ -h, --help show this help message and exit\r
+ -file FILE, -f FILE The svg file need to be converted.\r
+ -dir DIR, -d DIR The directory needs to be converted.\r
+ -output OUTPUT output dir\r
+\r
+example:\r
+windows: python .\main.py -dir .\instance\analogue_dial\r
+windows: python .\main.py -dir .\instance\kaleidoscope_dial
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from enum import Enum\r
+from ctypes import *\r
+\r
+class Point(Structure):\r
+ _fields_ = [\r
+ ('x', c_short),\r
+ ('y', c_short),\r
+ ]\r
+\r
+class Rect(Structure):\r
+ _fields_ = [\r
+ ('x', c_short),\r
+ ('y', c_short),\r
+ ('w', c_ushort),\r
+ ('h', c_ushort)\r
+ ]\r
+\r
+class ColorStop(Structure):\r
+ _fields_ = [\r
+ ('stop', c_float),\r
+ ('color', c_uint),\r
+ ]
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import os\r
+import re\r
+import struct\r
+import ctypes\r
+from ctypes import *\r
+import xml.sax\r
+from enum import Enum\r
+import img_convert\r
+import video_convert\r
+from dial_static_img import DialStaticImg\r
+from dial_sequence_img import DialSequenceImg\r
+from dial_rotate_img import DialRotateImg\r
+from dial_option_img import DialOptionImg\r
+from dial_digital_img import DialDigitalImg\r
+from dial_label import DialLabel\r
+from dial_arc_label import DialArcLabel\r
+from dial_box_progress import DialBoxProgress\r
+from dial_arc_progress import DialArcProgress\r
+from dial_video import DialVideo\r
+from dial_click import DialClick\r
+from dial_kaleidoscope import DialKaleidoscope\r
+\r
+class DialHeader(Structure):\r
+ _fields_ = [\r
+ ('dialName', c_char * 16),\r
+ ('width', c_short),\r
+ ('height', c_short),\r
+ ('version', c_char * 16),\r
+ ('previewImgId', c_ushort),\r
+ ('description', c_char * 128),\r
+ ('imgoffset', c_uint),\r
+ ('period', c_ubyte),\r
+ ('dialViewCount', c_ubyte),\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.imgoffset = 0\r
+ self.dialViewCount = 0\r
+ self.period = 0\r
+ self.viewType = []\r
+ self.viewPt = []\r
+\r
+ def parse_attributes(self, attributes):\r
+ title = attributes["title"]\r
+ self.dialName = bytes(title, encoding = "utf8")\r
+\r
+ description = attributes["description"]\r
+ self.description = bytes(description, encoding = "utf8")\r
+\r
+ size = attributes["size"]\r
+ width,height = size.split(' ')\r
+ self.width = int(width)\r
+ self.height = int(height)\r
+\r
+ version = attributes["version"]\r
+ self.version = bytes(version, encoding = "utf8")\r
+\r
+ previewStr = attributes["preview_img"]\r
+ self.previewImgId = img_convert.instance.convert_img(previewStr)\r
+\r
+ for attr in attributes.getNames():\r
+ if attr == "tile_width":\r
+ tile_width = int(attributes["tile_width"])\r
+ img_conver.instance.set_tile_width(tile_width)\r
+\r
+ def add_view(self, viewObj, viewType):\r
+ self.viewPt.append(viewObj)\r
+ self.viewType.append(viewType)\r
+ self.dialViewCount += 1\r
+\r
+ def get_bytes(self):\r
+ ret = bytes(self)\r
+ for index in range(self.dialViewCount):\r
+ ret += struct.pack('@b', self.viewType[index])\r
+ return ret\r
+\r
+ def get_size(self):\r
+ return sizeof(self) + sizeof(c_ubyte) * self.dialViewCount\r
+\r
+class DialConvertTool(xml.sax.ContentHandler):\r
+ parser = xml.sax.make_parser()\r
+ DIAL_STATIC_IMG_TYPE = 0\r
+ DIAL_SEQUENCE_IMG_TYPE = 1\r
+ DIAL_ROTATE_IMG_TYPE = 2\r
+ DIAL_OPTION_IMG_TYPE = 3\r
+ DIAL_DIGITAL_IMG_TYPE = 4\r
+ DIAL_LABEL_TYPE = 5\r
+ DIAL_ARC_LABEL_TYPE = 6\r
+ DIAL_BOX_PROGRESS_TYPE = 7\r
+ DIAL_ARC_PROGRESS_TYPE = 8\r
+ DIAL_VIDEO_TYPE = 9\r
+ DIAL_CLICK_TYPE = 10\r
+ DIAL_KALEIDOSCCOPE_TYPE = 11\r
+\r
+ def __init__(self):\r
+ self.inFile = ""\r
+ self.outPath = ""\r
+ self.header = DialHeader()\r
+ self.parser.setFeature(xml.sax.handler.feature_namespaces, 0)\r
+ self.parser.setContentHandler(self)\r
+\r
+ def startElement(self, tag, attributes):\r
+ viewTypeArray = []\r
+ if tag == "dial":\r
+ self.header.parse_attributes(attributes)\r
+ elif tag == "static_img":\r
+ view = DialStaticImg()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_STATIC_IMG_TYPE)\r
+ elif tag == "sequence_img":\r
+ view = DialSequenceImg()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_SEQUENCE_IMG_TYPE)\r
+ elif tag == "rotate_img":\r
+ view = DialRotateImg()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_ROTATE_IMG_TYPE)\r
+ elif tag == "option_img":\r
+ view = DialOptionImg()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_OPTION_IMG_TYPE)\r
+ elif tag == "digital_img":\r
+ view = DialDigitalImg()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_DIGITAL_IMG_TYPE)\r
+ elif tag == "label":\r
+ view = DialLabel()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_LABEL_TYPE)\r
+ elif tag == "arc_label":\r
+ view = DialArcLabel()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_ARC_LABEL_TYPE)\r
+ elif tag == "box_progress":\r
+ view = DialBoxProgress()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_BOX_PROGRESS_TYPE)\r
+ elif tag == "arc_progress":\r
+ view = DialArcProgress()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_ARC_PROGRESS_TYPE)\r
+ elif tag == "video":\r
+ view = DialVideo()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_VIDEO_TYPE)\r
+ elif tag == "click":\r
+ view = DialClick()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_CLICK_TYPE)\r
+ elif tag == "kaleidoscope":\r
+ view = DialKaleidoscope()\r
+ view.parse_attributes(attributes)\r
+ self.header.add_view(view, self.DIAL_KALEIDOSCCOPE_TYPE)\r
+\r
+ def endElement(self, tag):\r
+ if tag == "dial":\r
+ # create & open dstfile\r
+ outputfile = self.outPath + "/" + os.path.basename(self.inFile)[:-3] + "bin"\r
+ fb = open(outputfile, 'wb')\r
+ os.chmod(outputfile, 0o0755)\r
+ self._write_data_to_bin(fb)\r
+ fb.close()\r
+\r
+ def convert_xml_to_output(self, inFile, outPath):\r
+ self.inFile = inFile\r
+ self.outPath = outPath\r
+ self.parser.parse(inFile)\r
+\r
+ def _write_data_to_bin(self, fb):\r
+ self.header.imgoffset += self.header.get_size()\r
+ for view in self.header.viewPt:\r
+ if self.header.period < view.period:\r
+ self.header.period = view.period\r
+ self.header.imgoffset += view.get_size()\r
+\r
+ fb.write(self.header.get_bytes())\r
+ for view in self.header.viewPt:\r
+ if isinstance(view, DialVideo):\r
+ view.offset += self.header.imgoffset + img_convert.instance.get_size()\r
+ fb.write(view.get_bytes())\r
+ img_convert.instance.write_data_to_bin(fb)\r
+ video_convert.instance.write_data_to_bin(fb)\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+\r
+class DialArcLabel(Structure):\r
+ _fields_ = [\r
+ ('align', c_ubyte),\r
+ ('fontSize', c_ubyte),\r
+ ('center', Point),\r
+ ('radius', c_ushort),\r
+ ('rotateStart', c_short),\r
+ ('rotaeteEnd', c_short),\r
+ ('color', c_uint),\r
+ ('fontName', c_char * 64),\r
+ ('text', c_char * 64),\r
+ ('bindData', c_short),\r
+ ('isPeriod', c_bool)\r
+ ]\r
+ def __init__(self):\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ alignStr = attributes["align"]\r
+ if alignStr == "bottom":\r
+ self.align = 4\r
+ elif alignStr == "top":\r
+ self.align = 3\r
+ elif alignStr == "center":\r
+ self.align = 2\r
+ elif alignStr == "right":\r
+ self.align = 1\r
+ else:\r
+ self.align = 0\r
+\r
+ self.fontSize = int(attributes["font_size"])\r
+\r
+ x,y = attributes["center"].split(" ")\r
+ self.center.x = int(x)\r
+ self.center.y = int(y)\r
+\r
+ self.radius = int(attributes["radius"])\r
+ self.rotateStart = int(attributes["start_angle"])\r
+ self.rotaeteEnd = int(attributes["end_angle"])\r
+ self.color = int(attributes["color"], 16)\r
+ self.fontName = bytes(attributes["font"], encoding = "utf8")\r
+ self.text = bytes(attributes["text"], encoding = "utf8")\r
+ for attr in attributes.getNames():\r
+ if attr == "bind_data":\r
+ self.bindData = int(attributes["bind_data"])\r
+ elif attr == "period":\r
+ self.period = int(attributes["period"])\r
+ if self.period != 0:\r
+ self.isPeriod = True\r
+ if self.isPeriod != 0 and self.bindData == 0:\r
+ print("[ERROR]:[bind_data] is not set, [period] cannot be set")\r
+ sys.exit(1)\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+from common_types import ColorStop\r
+import img_convert\r
+\r
+class ProgressUnion(Union):\r
+ _fields_ = [\r
+ ('stopCount', c_ubyte),\r
+ ('imgId', c_ushort),\r
+ ('color', c_uint),\r
+ ]\r
+\r
+class DialArcProgress(Structure):\r
+ _fields_ = [\r
+ ('cap', c_ubyte),\r
+ ('isPeriod', c_bool),\r
+ ('radius', c_ushort),\r
+ ('startAngle', c_ushort),\r
+ ('endAngle', c_ushort),\r
+ ('lineWidth', c_ushort),\r
+ ('bindData', c_short),\r
+ ('bgColor', c_uint),\r
+ ('type', c_ubyte),\r
+ ('rect', Rect),\r
+ ('unionValue', ProgressUnion)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.stop = []\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y,w,h = attributes["rect"].split(" ")\r
+ self.rect.x = int(x)\r
+ self.rect.y = int(y)\r
+ self.rect.w = int(w)\r
+ self.rect.h = int(h)\r
+\r
+ cap = attributes["cap_type"]\r
+ if cap == "round":\r
+ self.cap = 1\r
+ else:\r
+ self.cap = 0\r
+\r
+ self.radius = int(attributes["radius"])\r
+ self.startAngle = int(attributes["start_angle"])\r
+ self.endAngle = int(attributes["end_angle"])\r
+ self.lineWidth = int(attributes["line_width"])\r
+ self.bindData = int(attributes["bind_data"])\r
+\r
+ attrList = attributes.getNames()\r
+ for attr in attrList:\r
+ if attr == "img_name":\r
+ self.unionValue.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+ self.type = 0\r
+ break\r
+ elif attr == "color":\r
+ self.unionValue.color = int(attributes["color"], 16)\r
+ self.type = 1\r
+ break\r
+ elif attr == "gradient_colors":\r
+ self.type = 2\r
+ stopList = attributes["gradient_stops"].split(" ")\r
+ colorList = attributes["gradient_colors"].split(" ")\r
+ if len(stopList) != len(colorList):\r
+ print("[ERROR]:[gradient_stops] attr not equal [colorList] attr")\r
+ self.unionValue.stopCount = min(len(colorList), len(stopList))\r
+ for index in range(self.unionValue.stopCount):\r
+ colorStop = ColorStop()\r
+ colorStop.stop = float(stopList[index])\r
+ colorStop.color = int(colorList[index], 16)\r
+ self.stop.append(colorStop)\r
+ break\r
+\r
+ if "period" in attrList:\r
+ self.period = int(attributes["period"])\r
+ if (self.period != 0):\r
+ self.isPeriod = True\r
+\r
+ if "background_color" in attrList:\r
+ self.bgColor = int(attributes["background_color"], 16)\r
+\r
+ def get_bytes(self):\r
+ ret = bytes(self)\r
+ if self.type == 2:\r
+ for stop in self.stop:\r
+ ret += bytes(stop)\r
+ return ret\r
+\r
+ def get_size(self):\r
+ ret = sizeof(self)\r
+ if self.type == 2:\r
+ for stop in self.stop:\r
+ ret += sizeof(stop)\r
+ return ret
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+from common_types import ColorStop\r
+import img_convert\r
+\r
+class ProgressUnion(Union):\r
+ _fields_ = [\r
+ ('stopCount', c_ubyte),\r
+ ('imgId', c_ushort),\r
+ ('color', c_uint),\r
+ ]\r
+\r
+class DialBoxProgress(Structure):\r
+ _fields_ = [\r
+ ('cap', c_ubyte),\r
+ ('direction', c_ubyte),\r
+ ('isPeriod', c_bool),\r
+ ('bindData', c_short),\r
+ ('bgColor', c_uint),\r
+ ('type', c_ubyte),\r
+ ('rect', Rect),\r
+ ('unionValue', ProgressUnion)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.stop = []\r
+ self.isPeriod = False\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y,w,h = attributes["rect"].split(" ")\r
+ self.rect.x = int(x)\r
+ self.rect.y = int(y)\r
+ self.rect.w = int(w)\r
+ self.rect.h = int(h)\r
+\r
+ cap = attributes["cap_type"]\r
+ if cap == "round":\r
+ self.cap = 1\r
+ else:\r
+ self.cap = 0\r
+\r
+ direction = attributes["direction"]\r
+ if direction == "left_to_right":\r
+ self.direction = 0\r
+ elif direction == "right_to_left":\r
+ self.direction = 1\r
+ elif direction == "top_to_bottom":\r
+ self.direction = 2\r
+ elif direction == "bottom_to_top":\r
+ self.direction = 3\r
+\r
+ self.bindData = int(attributes["bind_data"])\r
+\r
+ attrList = attributes.getNames()\r
+ for attr in attrList:\r
+ if attr == "img_name":\r
+ self.unionValue.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+ self.type = 0\r
+ break\r
+ elif attr == "color":\r
+ self.unionValue.color = int(attributes["color"], 16)\r
+ self.type = 1\r
+ break\r
+ elif attr == "gradient_colors":\r
+ stopList = attributes["gradient_stops"].split(" ")\r
+ colorList = attributes["gradient_colors"].split(" ")\r
+ if len(stopList) != len(colorList):\r
+ print("[ERROR]:[gradient_stops] attr not equal [colorList] attr")\r
+ self.unionValue.stopCount = min(len(colorList), len(stopList))\r
+ for index in range(self.unionValue.stopCount):\r
+ colorStop = ColorStop()\r
+ colorStop.stop = float(stopList[index])\r
+ colorStop.color = int(colorList[index], 16)\r
+ self.stop.append(colorStop)\r
+ self.type = 2\r
+ break\r
+\r
+ if "period" in attrList:\r
+ self.period = int(attributes["period"])\r
+ if (self.period != 0) :\r
+ self.isPeriod = True\r
+ if "background_color" in attrList:\r
+ self.bgColor = int(attributes["background_color"], 16)\r
+\r
+ def get_bytes(self):\r
+ ret = bytes(self)\r
+ if self.type == 2:\r
+ for stop in self.stop:\r
+ ret += bytes(stop)\r
+ return ret\r
+\r
+ def get_size(self):\r
+ ret = sizeof(self)\r
+ if self.type == 2:\r
+ for stop in self.stop:\r
+ ret += sizeof(stop)\r
+ return ret
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+\r
+class ClickTypeUnion(Union):\r
+ _fields_ = [\r
+ ('sliceId', c_uint),\r
+ ('bundleName', c_char * 64)\r
+ ]\r
+\r
+class DialClick(Structure):\r
+ _fields_ = [\r
+ ('type', c_ubyte),\r
+ ('rect', Rect),\r
+ ('unionType', ClickTypeUnion),\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y,w,h = attributes["rect"].split(" ")\r
+ self.rect.x = int(x)\r
+ self.rect.y = int(y)\r
+ self.rect.w = int(w)\r
+ self.rect.h = int(h)\r
+\r
+ for attr in attributes.getNames():\r
+ if attr == "action_slice":\r
+ self.unionType.sliceId = int(attributes["action_slice"])\r
+ self.type = 0\r
+ break\r
+ elif attr == "action_bundle":\r
+ self.unionType.bundleName = bytes(attributes["action_bundle"], encoding = "utf8")\r
+ self.type = 1\r
+ break\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialDigitalImg(Structure):\r
+ _fields_ = [\r
+ ('alignType', c_ubyte, 4),\r
+ ('integerLength', c_ubyte, 4),\r
+ ('decimalPrecision', c_ubyte),\r
+ ('imgIds', c_ushort * 10),\r
+ ('signImgId', c_ushort),\r
+ ('decimalPointImgId', c_ushort),\r
+ ('space', c_ushort),\r
+ ('alignPosition', Point),\r
+ ('bindData', c_short),\r
+ ('isPeriod', c_bool)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ imgNames = attributes["img_names"].split(",")\r
+ length = len(imgNames)\r
+ if length < 10:\r
+ print("[ERR]:tag:[digital_img] attr[img_names] less than 10!")\r
+ sys.exit(1)\r
+ else:\r
+ for index in range(10):\r
+ self.imgIds[index] = img_convert.instance.convert_img(imgNames[index])\r
+\r
+ self.space = int(attributes["space"])\r
+ alignStr = attributes["align"]\r
+ if alignStr == "right":\r
+ self.alignType = 2\r
+ elif alignStr == "center":\r
+ self.alignType = 1\r
+ else:\r
+ self.alignType = 0\r
+ x,y = attributes["align_pos"].split(" ")\r
+ self.alignPosition.x = int(x)\r
+ self.alignPosition.y = int(y)\r
+ self.bindData = int(attributes["bind_data"])\r
+\r
+ for attr in attributes.getNames():\r
+ if attr == "sign_img_name":\r
+ signImgName = attributes["sign_img_name"]\r
+ self.signImgId = img_convert.instance.convert_img(signImgName)\r
+ elif attr == "integer_length":\r
+ self.integerLength = int(attributes["integer_length"])\r
+ elif attr == "img_decimal_point":\r
+ decimalPointImgName = attributes["img_decimal_point"]\r
+ self.decimalPointImgId = img_convert.instance.convert_img(decimalPointImgName)\r
+ elif attr == "decimal_precision":\r
+ self.decimalPrecision = int(attributes["decimal_precision"])\r
+ elif attr == "period":\r
+ self.period = int(attributes["period"])\r
+ if self.period != 0:\r
+ self.isPeriod = True\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+import img_convert\r
+\r
+class DialKaleidoscope(Structure):\r
+ _fields_ = [\r
+ ('imgId', c_ushort),\r
+ ('rotateEventFactor', c_float),\r
+ ('rotateAnimatorValue', c_float)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.imgId = 0\r
+ self.rotateEventFactor = 1.0\r
+ self.rotateAnimatorValue = 0.0\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+ for attr in attributes.getNames():\r
+ if attr == "crown_rotate_step":\r
+ self.rotateEventFactor = float(attributes["crown_rotate_step"])\r
+ elif attr == "animator_rotate_step":\r
+ self.rotateAnimatorValue = float(attributes["animator_rotate_step"])\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+\r
+class DialLabel(Structure):\r
+ _fields_ = [\r
+ ('breakMode', c_ubyte),\r
+ ('align', c_ubyte),\r
+ ('fontSize', c_ubyte),\r
+ ('isPeriod', c_bool),\r
+ ('rect', Rect),\r
+ ('color', c_uint),\r
+ ('fontName', c_char * 64),\r
+ ('text', c_char * 64),\r
+ ('bindData', c_short)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y,w,h = attributes["rect"].split(" ")\r
+ self.rect.x = int(x)\r
+ self.rect.y = int(y)\r
+ self.rect.w = int(w)\r
+ self.rect.h = int(h)\r
+\r
+ mode = attributes["break_mode"]\r
+ if mode == "adapt":\r
+ self.breakMode = 0\r
+ elif mode == "stretch":\r
+ self.breakMode = 1\r
+ elif mode == "wrap":\r
+ self.breakMode = 2\r
+ elif mode == "ellipsis":\r
+ self.breakMode = 3\r
+ elif mode == "marquee":\r
+ self.breakMode = 4\r
+ elif mode == "clip":\r
+ self.breakMode = 5\r
+ else:\r
+ self.breakMode = 3\r
+ print("[WARING][label:break_mode]Incorrect input:", mode)\r
+\r
+ alignStr = attributes["align"]\r
+ if alignStr == "bottom":\r
+ self.align = 4\r
+ elif alignStr == "top":\r
+ self.align = 3\r
+ elif alignStr == "center":\r
+ self.align = 2\r
+ elif alignStr == "right":\r
+ self.align = 1\r
+ elif alignStr == "left":\r
+ self.align = 0\r
+ else:\r
+ self.align = 0\r
+ print("[WARING][label:align]Incorrect input:", alignStr)\r
+\r
+ self.fontSize = int(attributes["font_size"])\r
+ self.color = int(attributes["color"], 16)\r
+ self.fontName = bytes(attributes["font"], encoding = "utf8")\r
+ self.text = bytes(attributes["text"], encoding = "utf8")\r
+\r
+ for attr in attributes.getNames():\r
+ if attr == "bind_data":\r
+ self.bindData = int(attributes["bind_data"])\r
+ elif attr == "period":\r
+ self.period = int(attributes["period"])\r
+ if self.period != 0:\r
+ self.isPeriod = True\r
+ if self.isPeriod != 0 and self.bindData == 0:\r
+ print("[ERROR]:[bind_data] is not set, [period] cannot be set")\r
+ sys.exit(1)\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialOptionImg(Structure):\r
+ _fields_ = [\r
+ ('pos', Point),\r
+ ('bindData', c_short),\r
+ ('isPeriod', c_bool),\r
+ ('count', c_ubyte),\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.imgId = []\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y = attributes["position"].split(" ")\r
+ self.pos.x = int(x)\r
+ self.pos.y = int(y)\r
+\r
+ self.bindData = int(attributes["bind_data"])\r
+\r
+ imgNames = attributes["img_names"].split(",")\r
+ self.count = len(imgNames)\r
+ for img in imgNames:\r
+ imgId = img_convert.instance.convert_img(img)\r
+ self.imgId.append(imgId)\r
+\r
+ if "period" in attributes.getNames():\r
+ self.period = int(attributes["period"])\r
+ if self.period != 0:\r
+ self.isPeriod = True\r
+\r
+ def get_bytes(self):\r
+ ret = bytes(self)\r
+ for index in range(self.count):\r
+ ret += struct.pack('@H', self.imgId[index])\r
+ return ret\r
+\r
+ def get_size(self):\r
+ return sizeof(self) + sizeof(c_ushort) * self.count
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialRotateImg(Structure):\r
+ _fields_ = [\r
+ ('pos', Point),\r
+ ('center', Point),\r
+ ('rotateStart', c_short),\r
+ ('rotaeteEnd', c_short),\r
+ ('imgId', c_ushort),\r
+ ('bindData', c_short),\r
+ ('isPeriod', c_bool)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.period = 0\r
+ self.isPeriod = False\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y = attributes["position"].split(" ")\r
+ self.pos.x = int(x)\r
+ self.pos.y = int(y)\r
+\r
+ x,y = attributes["rotate_center"].split(" ")\r
+ self.center.x = round(float(x))\r
+ self.center.y = round(float(y))\r
+\r
+ self.rotateStart = int(attributes["rotate_start"])\r
+ self.rotaeteEnd = int(attributes["rotate_end"])\r
+\r
+ self.bindData = int(attributes["bind_data"])\r
+\r
+ self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+ if "period" in attributes.getNames():\r
+ self.period = int(attributes["period"])\r
+ if self.period != 0:\r
+ self.isPeriod = True\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialSequenceImg(Structure):\r
+ _fields_ = [\r
+ ('pos', Point),\r
+ ('interval', c_ushort),\r
+ ('repeat', c_bool),\r
+ ('imgNum', c_ubyte),\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.imgId = []\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y = attributes["position"].split(" ")\r
+ self.pos.x = int(x)\r
+ self.pos.y = int(y)\r
+\r
+ if attributes["repeat"].lower() == "true":\r
+ self.repeat = True\r
+ elif attributes["repeat"].lower() == "false":\r
+ self.repeat = False\r
+\r
+ interval = int(attributes["interval"])\r
+ if interval < 0:\r
+ print("[ERROR]: [interval] attr less than 0")\r
+ sys.exit(1)\r
+ else:\r
+ self.interval = interval\r
+\r
+ imgNames = attributes["img_names"].split(",")\r
+ self.imgNum = len(imgNames)\r
+ for img in imgNames:\r
+ imgId = img_convert.instance.convert_img(img)\r
+ self.imgId.append(imgId)\r
+\r
+ def get_bytes(self):\r
+ ret = bytes(self)\r
+ for index in range(self.imgNum):\r
+ ret += struct.pack('@H', self.imgId[index])\r
+ return ret\r
+\r
+ def get_size(self):\r
+ return sizeof(self) + sizeof(c_ushort) * self.imgNum
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialStaticImg(Structure):\r
+ _fields_ = [\r
+ ('pos', Point),\r
+ ('center', Point),\r
+ ('rotate', c_float),\r
+ ('imgId', c_ushort)\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.imgId = 0\r
+ self.pos.x = 0\r
+ self.pos.y = 0\r
+ self.center.x = 0\r
+ self.center.y = 0\r
+ self.rotate = 0.0\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y = attributes["position"].split(" ")\r
+ self.pos.x = int(x)\r
+ self.pos.y = int(y)\r
+\r
+ self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+\r
+ for attr in attributes.getNames():\r
+ if attr == "center":\r
+ x,y = attributes["center"].split(" ")\r
+ self.center.x = int(x)\r
+ self.center.y = int(y)\r
+ elif attr == "rotate":\r
+ self.rotate = float(attributes["rotate"])\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+import video_convert\r
+import img_convert\r
+\r
+class DialVideo(Structure):\r
+ _fields_ = [\r
+ ('rect', Rect),\r
+ ('offset', c_uint),\r
+ ('colorKey', c_uint),\r
+ ('imgId', c_uint),\r
+ ]\r
+\r
+ def __init__(self):\r
+ self.period = 0\r
+\r
+ def parse_attributes(self, attributes):\r
+ x,y,w,h = attributes["rect"].split(" ")\r
+ self.rect.x = int(x)\r
+ self.rect.y = int(y)\r
+ self.rect.w = int(w)\r
+ self.rect.h = int(h)\r
+\r
+ self.colorKey = int(attributes["color_key"], 16)\r
+\r
+ self.offset = video_convert.instance.convert_video(attributes["source"])\r
+\r
+ self.imgId = img_convert.instance.convert_img(attributes["preview_frame"])\r
+\r
+ def get_bytes(self):\r
+ return bytes(self)\r
+\r
+ def get_size(self):\r
+ return sizeof(self)
\ No newline at end of file
--- /dev/null
+import base64\r
+from PIL import Image\r
+from io import BytesIO\r
+import cv2\r
+import ctypes\r
+from ctypes import *\r
+from PIL import Image\r
+\r
+import os\r
+import sys\r
+import struct\r
+import time\r
+import platform\r
+import numpy as np\r
+import pickle as p\r
+import requests\r
+import matplotlib.pyplot as pyplot\r
+\r
+global dll\r
+if platform.system().lower() == 'windows':\r
+ dll = ctypes.CDLL(r".\dll\x64\release_cs\ICE_V5R1_BLOCK_HTC.dll")\r
+elif platform.system().lower() == 'linux':\r
+ dll = ctypes.CDLL(sys.path[0] + r"/dll/linux_cs/libcodec.so")\r
+\r
+class Header(ctypes.Structure):\r
+ _fields_ = [\r
+ ("width", c_uint),\r
+ ("height", c_uint),\r
+ ("stride", c_uint),\r
+ ("pixel_format", c_uint),\r
+ ("tile_width", c_uint),\r
+ ("mode_alpha", c_uint),\r
+ ("mode_rgb", c_uint)\r
+ ]\r
+\r
+class BsData(ctypes.Structure):\r
+ _fields_ = [\r
+ ("bs_data", POINTER(c_ubyte)),\r
+ ("data_size", c_uint),\r
+ ("cmp_ratio", c_uint),\r
+ ("is_valid", c_uint),\r
+ ("subjective_review", c_uint),\r
+ ("para", Header)\r
+ ]\r
+\r
+class AutoCmpOutput(ctypes.Structure):\r
+ _fields_ = [\r
+ ("cmp_bs0", POINTER(BsData)),\r
+ ("cmp_bs1", POINTER(BsData)),\r
+ ("cmp_bs2", POINTER(BsData)),\r
+ ("cmp_bs3", POINTER(BsData)),\r
+ ("auto_cmp_mode", c_uint),\r
+ ("valid_bs_num", c_uint)\r
+ ]\r
+\r
+class CmpInput(ctypes.Structure):\r
+ _fields_ = [\r
+ ("width", c_uint),\r
+ ("height", c_uint),\r
+ ("stride", c_uint),\r
+ ("pixel_format", c_uint),\r
+ ("tile_width", c_uint),\r
+ ("mode_alpha", c_uint),\r
+ ("mode_rgb", c_uint),\r
+ ("red_channel", POINTER(c_ubyte)),\r
+ ("green_channel", POINTER(c_ubyte)),\r
+ ("blue_channel", POINTER(c_ubyte)),\r
+ ("alpha_channel", POINTER(c_ubyte))\r
+ ]\r
+\r
+class AutoCmpInput(ctypes.Structure):\r
+ _fields_ =[\r
+ ("auto_cmp_mode", c_uint),\r
+ ("high_quality_mode", c_uint),\r
+ ("high_cmp_ratio_mode", c_uint),\r
+ ("cmp_in", POINTER(CmpInput))\r
+ ]\r
+\r
+class BinHeader(ctypes.Structure):\r
+ _fields_ = [\r
+ ("dirId", c_uint),\r
+ ("count", c_uint)\r
+ ]\r
+\r
+class SeekInfo(ctypes.Structure):\r
+ _fields_ = [\r
+ ("offset", c_uint),\r
+ ("size", c_uint)\r
+ ]\r
+\r
+class ImageHeader(ctypes.Structure):\r
+ _fields_ = [\r
+ ("colorMode", c_uint, 8),\r
+ ("version", c_uint, 4),\r
+ ("compressMode", c_uint, 4),\r
+ ("reserved", c_uint, 16),\r
+ ("width", c_ushort),\r
+ ("height", c_ushort)\r
+ ]\r
+\r
+class ImageConverTool():\r
+ binHeader = BinHeader()\r
+ binHeader.dirId = 0xfef\r
+ seekInfo = []\r
+ imageHeader = []\r
+ imageData = []\r
+ imageNum = 0\r
+ isConvertedFile = []\r
+\r
+ def __init__(self):\r
+ self.markCurOffset = 0\r
+ self.width = 0\r
+ self.height = 0\r
+ self.file_alpha = False\r
+ self.cmp_mode = "HFBC"\r
+ self.color_fmt = ' '\r
+ self.align = 1\r
+ self.tile_width = 6\r
+ self.mode_alpha = 1\r
+ self.mode_rgb = 1\r
+ self.auto_cmp_mode = 0\r
+ self.high_quality_mode = 0\r
+ self.high_cmp_ratio_mode = 0\r
+ self.version = 1\r
+\r
+ def set_tile_width(self, tile_width):\r
+ if tile_width not in self.tile_width_support:\r
+ print("[ERROR]:The tile_width value is not supported.")\r
+ sys.exit(1)\r
+\r
+ self.tile_width = tile_width\r
+\r
+ def _convert(self):\r
+ width, height = self.image.size\r
+ self.width = width\r
+ self.height = height\r
+ self.stride_pixel = (self.width + self.align - 1) // self.align * self.align\r
+ if len(self.image.split()) > 3:\r
+ self.file_alpha = True\r
+ else:\r
+ self.file_alpha = False\r
+\r
+ # initialize CmpInput\r
+ cmp_input = CmpInput()\r
+ self._get_cmp_input(cmp_input)\r
+ auto_cmp_input = AutoCmpInput()\r
+ self._get_auto_cmp_input(auto_cmp_input, cmp_input)\r
+\r
+ # call GetBufferSize to get buffer size\r
+ # initialize CmpOutput\r
+ auto_cmp_output = AutoCmpOutput()\r
+\r
+ cmp_bs0 = BsData()\r
+ buf_size0 = dll.ice_v5r1_block_get_buffer_size(byref(cmp_input)) # 压缩后输出数据的大小\r
+ cmp_bs0.bs_data = (c_ubyte * buf_size0)()\r
+ auto_cmp_output.cmp_bs0 = ctypes.cast(pointer(cmp_bs0), POINTER(BsData))\r
+ ret = dll.ice_v5r1_block_htc_auto_cmp(byref(auto_cmp_input), byref(auto_cmp_output)) # 对输入数据进行压缩返回值是函数正常运行标志位\r
+\r
+ # add imageinfo to list\r
+ self.binHeader.count += 1\r
+\r
+ imageInfo = ImageHeader()\r
+ imageInfo.width = self.width\r
+ imageInfo.height = self.height\r
+ imageInfo.colorMode = self._get_color_mode()\r
+ imageInfo.version = 1\r
+ imageInfo.compressMode = 4\r
+ imageInfo.reserved = 0\r
+ seekInfo = SeekInfo()\r
+ seekInfo.offset = self.markCurOffset\r
+ seekInfo.size = sizeof(imageInfo) + cmp_bs0.data_size\r
+ self.markCurOffset += seekInfo.size\r
+ self.seekInfo.append(seekInfo)\r
+ self.imageHeader.append(imageInfo)\r
+ self.imageData.append(cmp_bs0)\r
+ self.imageNum += 1\r
+ return self.imageNum\r
+\r
+ def _check_path(self, path):\r
+ if not os.path.exists(path):\r
+ print("[ERROR]:", path, "is not exist")\r
+ return False\r
+ else:\r
+ if (not path[-3:].lower() == "png") and (not path[-3:].lower() == "jpg"):\r
+ print("[ERROR]:", path, "is not jpg or png format image")\r
+ return False\r
+ return True\r
+\r
+ def convert_img(self, path):\r
+ if path in self.isConvertedFile:\r
+ return self.isConvertedFile.index(path) + 1\r
+\r
+ if not self._check_path(path):\r
+ sys.exit(1)\r
+\r
+ self.image = Image.open(path)\r
+ if self.image.mode == 'RGBA':\r
+ self.color_fmt = 'ARGB8888'\r
+ elif self.image.mode == 'RGB':\r
+ self.color_fmt = 'RGB888'\r
+ self.isConvertedFile.append(path)\r
+ return self._convert()\r
+\r
+ def _get_cmp_px_format(self):\r
+ if self.color_fmt == 'RGB565':\r
+ return 2\r
+ elif self.color_fmt == 'RGB888':\r
+ return 0\r
+ elif self.color_fmt == 'ARGB8888':\r
+ return 1\r
+\r
+ def _get_color_mode(self):\r
+ if self.color_fmt == 'RGB565':\r
+ return 2\r
+ elif self.color_fmt == 'RGB888':\r
+ return 1\r
+ elif self.color_fmt == 'ARGB8888':\r
+ return 0\r
+\r
+ def _get_auto_cmp_input(self, auto_cmp_input, cmp_input):\r
+ auto_cmp_input.auto_cmp_mode = self.auto_cmp_mode\r
+ auto_cmp_input.high_quality_mode = self.high_quality_mode\r
+ auto_cmp_input.high_cmp_ratio_mode = self.high_cmp_ratio_mode\r
+ auto_cmp_input.cmp_in = ctypes.cast(pointer(cmp_input), POINTER(CmpInput))\r
+\r
+ def _get_cmp_input(self, cmp_input):\r
+ cmp_input.width = self.width\r
+ cmp_input.height = self.height\r
+ cmp_input.stride = self.width\r
+ cmp_input.tile_width = self.tile_width\r
+ cmp_input.mode_alpha = self.mode_alpha\r
+ cmp_input.mode_rgb = self.mode_rgb\r
+ cmp_input.pixel_format = self._get_cmp_px_format()\r
+ size = self.width * self.height\r
+ red = (c_ubyte * size)()\r
+ green = (c_ubyte * size)()\r
+ blue = (c_ubyte * size)()\r
+ alpha = (c_ubyte * size)()\r
+\r
+ for row in range(self.height):\r
+ for col in range(self.width):\r
+ position = row * self.width + col\r
+ red[position] = self.image.getdata()[position][0]\r
+ green[position] = self.image.getdata()[position][1]\r
+ blue[position] = self.image.getdata()[position][2]\r
+ if self.file_alpha == False:\r
+ alpha[position] = 0xFF\r
+ else:\r
+ alpha[position] = self.image.getdata()[position][3]\r
+ cmp_input.red_channel = red\r
+ cmp_input.green_channel = green\r
+ cmp_input.blue_channel = blue\r
+ cmp_input.alpha_channel = alpha\r
+\r
+ def write_data_to_bin(self, fb):\r
+ fb.write(bytes(self.binHeader))\r
+ for seek in self.seekInfo:\r
+ fb.write(bytes(seek))\r
+\r
+ for index in range(0, self.imageNum):\r
+ bt = bytearray()\r
+ color_fmt = self.imageHeader[index].colorMode\r
+ header = color_fmt + (self.imageHeader[index].width << 32) + \\r
+ (self.imageHeader[index].height << 48) + (self.imageHeader[index].version << 8)\r
+ header_bin = struct.pack("<Q", header)\r
+\r
+ if (self.cmp_mode == "HFBC"):\r
+ header = header + (4 << 12)\r
+ elif (self.cmp_mode == "HFBC_ABYPASS"):\r
+ header = header + (5 << 12)\r
+\r
+ header_bin = struct.pack("<Q", header)\r
+ bt += header_bin\r
+ for i in range(self.imageData[index].data_size):\r
+ bt += struct.pack("B", self.imageData[index].bs_data[i])\r
+ fb.writelines([bt])\r
+\r
+ def get_size(self):\r
+ ret = sizeof(self.binHeader)\r
+ ret += len(self.seekInfo) * sizeof(SeekInfo)\r
+ for index in range(0, self.imageNum):\r
+ bt = bytearray()\r
+ color_fmt = self._get_cmp_px_format()\r
+ header = color_fmt + (self.imageHeader[index].width << 32) + \\r
+ (self.imageHeader[index].height << 48) + (self.imageHeader[index].version << 8)\r
+ header_bin = struct.pack("<Q", header)\r
+\r
+ if (self.cmp_mode == "HFBC"):\r
+ header = header + (4 << 12)\r
+ elif (self.cmp_mode == "HFBC_ABYPASS"):\r
+ header = header + (5 << 12)\r
+\r
+ header_bin = struct.pack("<Q", header)\r
+ bt += header_bin\r
+ for i in range(self.imageData[index].data_size):\r
+ bt += struct.pack("B", self.imageData[index].bs_data[i])\r
+ ret += len(bt)\r
+ return ret\r
+\r
+instance = ImageConverTool()\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+# 1\ 解析命令 python main.py -d [DIR] -o [OUT_DIR]\r
+# 2\ 循环执行svg解析写入\r
+import sys\r
+import os\r
+import argparse\r
+from converter import DialConvertTool\r
+\r
+def GetParameters():\r
+ parser = argparse.ArgumentParser()\r
+\r
+ parser.add_argument('-file', '-f', type=str, default='', required=False,\r
+ help='The svg file need to be converted.')\r
+\r
+ parser.add_argument('-dir', '-d', type=str, default='', required=False,\r
+ help='The directory needs to be converted.')\r
+\r
+ parser.add_argument('-output', type=str, default=os.getcwd() + "/out", required=False,\r
+ help='output dir')\r
+\r
+ config = parser.parse_args()\r
+ return config\r
+\r
+if __name__ == "__main__":\r
+ userInput = GetParameters()\r
+ outputPath = userInput.output\r
+ inputFile = userInput.file\r
+ inputDir = userInput.dir\r
+ # Create an output folder.\r
+ print("output dir : " + outputPath)\r
+ if not os.path.exists(outputPath):\r
+ os.mkdir(outputPath)\r
+\r
+ if not os.path.isdir(inputFile) and inputFile[-3:].lower() == "xml":\r
+ print("input file : " + inputFile)\r
+ converter = DialConvertTool()\r
+ converter.convert_xml_to_output(inputFile, outputPath)\r
+\r
+ files = os.listdir(inputDir)\r
+ print("input dir : " + inputDir)\r
+ for file in files:\r
+ if not os.path.isdir(file) and file[-3:].lower() == "xml":\r
+ print("xml file : " + file)\r
+ converter = DialConvertTool()\r
+ converter.convert_xml_to_output(inputDir + "/" + file, outputPath)\r
+\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import ctypes\r
+from ctypes import *\r
+\r
+class VideoConvertTool:\r
+ def __init__(self):\r
+ self.videoNum = 0\r
+ self.videoName = []\r
+ self.videoIndex = []\r
+ self.videoData = bytearray()\r
+\r
+ def convert_video(self, path):\r
+ if path in self.videoName:\r
+ index = self.videoName.index(path)\r
+ return self.videoIndex[index]\r
+ fp = open(path, 'rb')\r
+ data = fp.read()\r
+ fp.close()\r
+ self.videoName.append(path)\r
+ self.videoNum += 1\r
+ ret = len(self.videoData)\r
+ self.videoIndex.append(ret)\r
+ self.videoData += data\r
+ return ret\r
+\r
+ def write_data_to_bin(self, fb):\r
+ fb.write(self.videoData)\r
+\r
+instance = VideoConvertTool()\r
--- /dev/null
+中文名:运动\r
+英文名:Sport\r
+标签:经典指针 运动
\ No newline at end of file
--- /dev/null
+中文名:万花筒\r
+英文名:Kaleidoscope\r
+标签:经典指针;动态
\ No newline at end of file
--- /dev/null
+中文名:KUMI\r
+英文名:KUMI\r
+标签:数码表盘
\ No newline at end of file
--- /dev/null
+中文名:水母\r
+英文名:Jellyfish\r
+标签:数码表盘;动物
\ No newline at end of file
--- /dev/null
+中文名:小狗\r
+英文名:Dog\r
+标签:经典指针;动物
\ No newline at end of file
--- /dev/null
+中文名:小猫\r
+英文名:Kitty\r
+标签:数码表盘;动态;动物
\ No newline at end of file
--- /dev/null
+中文名:指针几何\r
+英文名:Classic_Geometry\r
+标签:经典指针
\ No newline at end of file
--- /dev/null
+中文名:星空\r
+英文名:Galaxy\r
+标签:数码表盘;运动
\ No newline at end of file
--- /dev/null
+中文名:数码几何\r
+英文名:Digital_Geometry\r
+标签:数码表盘;动态
\ No newline at end of file
--- /dev/null
+中文名:招财猫\r
+英文名:Luckycat\r
+标签:经典指针;动物
\ No newline at end of file
--- /dev/null
+中文名:多肉\r
+英文名:Succulents\r
+标签:数码表盘;植物
\ No newline at end of file
--- /dev/null
+中文名:宇航员\r
+英文名:Spaceman\r
+标签:数码表盘;动态;人物
\ No newline at end of file
--- /dev/null
+中文名:卫星\r
+英文名:Satellite\r
+标签:数码表盘;动态
\ No newline at end of file
--- /dev/null
+中文名:飞鸟\r
+英文名:birdie\r
+标签:数码表盘,动物
\ No newline at end of file
--- /dev/null
+中文名:晨曦智影\r
+英文名:Dawn Insight\r
+标签:数码表盘、运动\r
+表盘描述:\r
+“晨曦智影”表盘将科技与生活完美融合,通过简洁的界面展现全天候健康数据。\r
+表盘顶部显示实时天气预报和日期,让你轻松掌握日常安排;\r
+中央大字体时间显示,清晰可读,便于快速查看。\r
+底部区域提供目标步数完成进度、心率、步数和卡路里消耗,智能健康管理一目了然。\r
+此外,表盘还整合了支付宝与AI助手快捷入口,让每一次支付和互动都迅速流畅。\r
+晨曦智影表盘为你带来不仅仅是时间的提示,更是对健康与效率的全面管理。
\ No newline at end of file
--- /dev/null
+中文名:黑曜律动\r
+英文名:Obsidian Rhythm\r
+标签:经典指针、动态表盘\r
+描述:\r
+“黑曜律动”表盘融合现代科技与独特个性,黑色基调搭配精致设计,\r
+彰显你的风格与效率。除了显示时间,它还提供便捷的快捷功能:\r
+● 点击12点位置进入天气应用,查看实时天气信息;\r
+● 点击6点位置查看今日步数,追踪健康数据;\r
+简约优雅的设计,让你在追求效率的同时,保持独一无二的风格。
\ No newline at end of file
--- /dev/null
+中文名:镜影行者\r
+英文名:Mirror Voyager\r
+标签:经典指针、动态表盘\r
+表盘描述:\r
+“镜影行者”表盘将现代时尚与经典腕表元素巧妙融合,\r
+采用三眼设计,左侧子表盘显示实时心率,红色指针与数值提供清晰的健康数据;\r
+右侧子表盘展示步数进展,象征每日目标的达成。\r
+中央计时秒针与外圈渐变的边缘设计则如同时光流逝中的步伐,赋予佩戴者在时间与健康管理中的平衡感。\r
+这款表盘在动感与优雅之间取得完美平衡,是智慧与品味的象征。
\ No newline at end of file
--- /dev/null
+中文名:蓝花\r
+英文名:blue flower\r
+标签:数码表盘;自然植物
\ No newline at end of file
--- /dev/null
+中文名:柠檬清新\r
+英文名:fresh lemon\r
+标签:数码表盘;食物元素
\ No newline at end of file
--- /dev/null
+中文名:可爱小鸭\r
+英文名:cute duck\r
+标签:数码表盘;趣味动物
\ No newline at end of file
--- /dev/null
+中文名:经典指针_黑\r
+英文名:classic_black\r
+标签:经典指针
\ No newline at end of file
--- /dev/null
+中文名:万圣南瓜\r
+英文名:pumpkin\r
+标签:数码表盘;节日活动
\ No newline at end of file
--- /dev/null
+中文名:玫瑰\r
+英文名:rose\r
+标签:数码表盘;自然植物
\ No newline at end of file
--- /dev/null
+中文名:白色铃兰花\r
+英文名:valley\r
+标签:数码表盘;自然植物
\ No newline at end of file
--- /dev/null
+中文名:海洋世界\r
+英文名:ocean world\r
+标签:数码表盘;趣味动物
\ No newline at end of file
--- /dev/null
+中文名:森林麋鹿\r
+英文名:forest elk\r
+标签:数码表盘;趣味动物
\ No newline at end of file
--- /dev/null
+中文名:修狗\r
+英文名:puppy\r
+标签:数码表盘;趣味动物
\ No newline at end of file
--- /dev/null
+中文名:花蕾\r
+英文名:bud\r
+标签:数码表盘;自然植物
\ No newline at end of file
--- /dev/null
+中文名:活力数字\r
+英文名:vibrant number\r
+标签:数码表盘;插画艺术
\ No newline at end of file
--- /dev/null
+中文名:炫酷光影\r
+英文名:shadow\r
+标签:经典指针;运动
\ No newline at end of file
--- /dev/null
+中文名:斗鱼\r
+英文名:fighting_fish\r
+标签:数码表盘;趣味动物
\ No newline at end of file
--- /dev/null
+中文名:大鹅\r
+英文名:goose\r
+标签:经典指针;插画艺术;动态
\ No newline at end of file
--- /dev/null
+中文名:露珠\r
+英文名:dewdrop\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:麋鹿\r
+英文名:elk\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:长颈鹿\r
+英文名:giraffe\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:荷花\r
+英文名:lotu\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:老鹰\r
+英文名:eagle\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:斑马\r
+英文名:zebra\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:小雏菊\r
+英文名:little daisy\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:狼\r
+英文名:wolf\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:熊\r
+英文名:bear\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:白玫瑰\r
+英文名:white rose\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:夜光水母\r
+英文名:glow jellyfish\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:小翠鸟\r
+英文名:kingfisher\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:大眼雀梅\r
+英文名:ornithogalum\r
+标签:数码表盘;自然植物
\ No newline at end of file
--- /dev/null
+中文名:狮子\r
+英文名:lion\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:沙皮狗\r
+英文名:shar pee\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:水瓶座\r
+英文名:Aquarius\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:射手座\r
+英文名:Sagittarius\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:狮子座\r
+英文名:Leo\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:金牛座\r
+英文名:Taurus\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:白羊座\r
+英文名:Aries\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:天秤座\r
+英文名:Libra\r
+标签:数码表盘;星座\r
--- /dev/null
+中文名:柯基\r
+英文名:corgi\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:仰望\r
+英文名:look up\r
+标签:数码表盘;自然景观\r
--- /dev/null
+中文名:绿叶\r
+英文名:greenery\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:黄昏\r
+英文名:dusk\r
+标签:数码表盘;自然景观\r
--- /dev/null
+中文名:小松鼠\r
+英文名:squirrel\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:蜥蜴\r
+英文名:lizard\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:灯塔\r
+英文名:lighthouse\r
+标签:数码表盘;城市风采\r
--- /dev/null
+中文名:波斯猫\r
+英文名:persian cat\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:都市夜色\r
+英文名:urban night\r
+标签:数码表盘;城市风采\r
--- /dev/null
+中文名:自然\r
+英文名:nature\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:梅花鹿\r
+英文名:sika deer\r
+标签:数码表盘;插画艺术\r
--- /dev/null
+中文名:烟花\r
+英文名:firework\r
+标签:数码表盘;节日活动\r
--- /dev/null
+中文名:粉树\r
+英文名:pink tree\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:湖泊\r
+英文名:lake\r
+标签:数码表盘;自然景观\r
--- /dev/null
+中文名:樱花\r
+英文名:sakura\r
+标签:数码表盘;自然植物\r
--- /dev/null
+中文名:蜗牛\r
+英文名:snails\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:小鸭\r
+英文名:duck\r
+标签:数码表盘;趣味动物\r
--- /dev/null
+中文名:深潜\r
+英文名:deep dive\r
+标签:数码表盘;自然景观\r
--- /dev/null
+中文名:波浪\r
+英文名:wave\r
+标签:数码表盘;插画艺术\r
--- /dev/null
+中文名:机械表盘_足球\r
+英文名:golden ball\r
+标签:经典指针;机械风格\r
--- /dev/null
+中文名:抽象线条\r
+英文名:abstract_lines\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_炫光\r
+英文名:line_glare\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_星球\r
+英文名:line_space\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_液化\r
+英文名:liquefaction\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_螳螂\r
+英文名:line_mantis\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_流动\r
+英文名:line_flow\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_梦境\r
+英文名:line_dream\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_花朵\r
+英文名:line_flower\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_螺旋\r
+英文名:line_spiral\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:爆炸\r
+英文名:explode\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:神经网络\r
+英文名:networks\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:扭曲\r
+英文名:distortion\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:线条_山谷\r
+英文名:line_valley\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:红色小球\r
+英文名:red_bal\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:大卫\r
+英文名:david\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:龙珠\r
+英文名:dragon_ball\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:科幻\r
+英文名:science\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:未来\r
+英文名:future\r
+标签:经典指针、插画艺术\r
--- /dev/null
+中文名:新年快乐\r
+英文名:Happy New Year\r
+标签:数码表盘;节日活动;新年表盘\r
--- /dev/null
+中文名:蛇年大吉\r
+英文名:Snake Year Luck\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:福娃贺岁\r
+英文名:Lucky Doll New\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:恭喜发财\r
+英文名:Wish You Wealth\r
+标签:数码表盘;节日活动;新年表盘\r
--- /dev/null
+中文名:好运连连\r
+英文名:Good Luck Forever\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:八方来财\r
+英文名:Wealth from All\r
+标签:数码表盘;节日活动;新年表盘\r
--- /dev/null
+中文名:喜迎2025\r
+英文名:Welcome 2025\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:元旦快乐\r
+英文名:New Year's Day\r
+标签:数码表盘;节日活动;新年表盘\r
--- /dev/null
+中文名:新春快乐\r
+英文名:Happy Spring\r
+标签:数码表盘;节日活动;新年表盘\r
--- /dev/null
+中文名:2025\r
+英文名:2025\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:蛇来运转\r
+英文名:Luck with Snake\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:蛇年吉祥\r
+英文名:Good Snake Year\r
+标签:数码表盘;新年表盘\r
--- /dev/null
+中文名:灯塔慧\r
+英文名:LighWisdom\r
+标签:数码表盘;\r
--- /dev/null
+LZMA SDK 21.07
+--------------
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA encoding, go to directory
+CPP/7zip/Bundles/LzmaCon
+and call make to recompile it:
+ make -f makefile.gcc clean all
--- /dev/null
+#!/bin/bash
+###
+# @Date: 2024-06-07 09:44:50
+# @LastEditors: Caisking 3449750381@qq.com
+# @LastEditTime: 2024-08-30 15:00:54
+# @FilePath: /FD230/tools/dial_converter_tool/make_tools/gen_dial_bin.sh
+###
+
+# 定义颜色常量,用于彩色输出
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[0;33m'
+NC='\033[0m'
+
+# 返回上一级目录
+cd .. || { echo -e "${RED}Error: Failed to change directory.${NC}"; exit 1; }
+
+# 检查并创建 out 和 dial_lzma 目录
+mkdir -p out dial_lzma || { echo -e "${RED}Error: Failed to create directories.${NC}"; exit 1; }
+
+# 定义 main.py 的路径
+MAIN_PY_PATH="dial_converter_tool/main.py"
+
+# 检查 main.py 文件是否存在
+if [ ! -f "$MAIN_PY_PATH" ]; then
+ echo -e "${RED}Error: main.py not found at $MAIN_PY_PATH.${NC}"
+ exit 1
+fi
+
+# 检查参数数量
+case $# in
+ 0)
+ # 没有参数,制作所有表盘
+ subdirs=(instance/*/)
+ ;;
+ 1)
+ # 一个参数,制作单个表盘
+ subdirs=("instance/${1#instance/}")
+ if [ ! -d "${subdirs[0]}" ]; then
+ echo -e "${RED}Error: Specified directory '${subdirs[0]}' does not exist.${NC}"
+ exit 1
+ fi
+ ;;
+ 2)
+ # 两个参数,制作指定范围的表盘
+ start_dir=$(basename "$1")
+ end_dir=$(basename "$2")
+ subdirs=()
+ for dir in instance/*/; do
+ dir_name=$(basename "$dir")
+ if [[ "$dir_name" =~ ^[0-9]+$ ]] && [ "$dir_name" -gt "$start_dir" ] && [ "$dir_name" -lt "$end_dir" ]; then
+ subdirs+=("$dir")
+ fi
+ done
+ if [ ${#subdirs[@]} -eq 0 ]; then
+ echo -e "${RED}Error: No directories found in the specified range.${NC}"
+ exit 1
+ fi
+ ;;
+ *)
+ # 参数数量超过2个,输出使用说明并退出
+ echo -e "${YELLOW}Usage: $0 [dial_folder] or $0 [start_dir] [end_dir]${NC}"
+ exit 1
+ ;;
+esac
+
+# 获取脚本所在目录
+# SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+# LZMA_TOOL_PATH="$SCRIPT_DIR/../lzma_tool/lzma_tool"
+
+# 遍历子目录处理表盘
+for subdir in "${subdirs[@]}"; do
+ # 提取子目录名称
+ dial=$(basename "$subdir")
+
+ # 查找子目录中的 XML 文件
+ xml_file=$(find "$subdir" -maxdepth 1 -type f -name "*.xml" -print -quit)
+ if [ -z "$xml_file" ]; then
+ echo -e "${RED}Error: XML file not found in $subdir${NC}"
+ continue
+ fi
+
+ # 计算文件数量和大小
+ dialfilecount=$(find "$subdir" -maxdepth 1 -type f | wc -l)
+ dialfilesize=$(du -sh "$subdir" | awk '{print $1}')
+
+ # 输出统计信息
+ echo -e "${YELLOW}Processing $dial [$dialfilecount files, $dialfilesize size]${NC}"
+
+ # 调用 main.py 处理子目录中的文件
+ if ! python "$MAIN_PY_PATH" -dir "$subdir" -output out/; then
+ echo -e "${RED}Error processing directory $dial${NC}"
+ continue
+ fi
+
+ # 压缩 .bin 文件到 .lzma 文件
+ bin_file="out/${xml_file##*/}"
+ bin_file="${bin_file%.xml}.bin"
+ lzma_file="dial_lzma/$dial/${xml_file##*/}"
+ lzma_file="${lzma_file%.xml}.lzma"
+
+
+ # 创建必要的目录
+ mkdir -p "$(dirname "$lzma_file")"
+
+ # 调用 lzma_tool(当前目录在dial)
+ if ! ./lzma_tool/lzma_tool -d12 -lc0 -lp0 e "$bin_file" "$lzma_file"; then
+ echo -e "${RED}lzma_tool directory $dial error${NC}"
+ else
+ echo -e "${GREEN}lzma_tool directory $dial ok${NC}"
+ fi
+done
\ No newline at end of file
--- /dev/null
+## 在liunx环境运行表盘脚本\r
+\r
+# 1.下载对应模块\r
+\r
+pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Pillow\r
+\r
+pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python\r
+\r
+pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib\r
+\r
+## 2.对表盘工具进行赋权限\r
+\r
+chmod +x gen_dial_bin.sh\r
+./gen_dial_bin.sh\r
+\r
+## 3.制作运行单个表盘\r
+\r
+python ./main.py -dir ./instance/1028/ -output ./out/\r
+\r
+#使用lzma_tool工具需要赋权限\r
+ chmod +x ../lzma_tool/lzma_tool\r
+\r
+### 更新版本 0830\r
+\r
+- 制作单个表盘以及lzma文件 **./gen_dial_bin.sh + 表盘文件夹路径**\r
+\r
+ ```\r
+ 示例 ./gen_dial_bin.sh ../instance/114/\r
+ ```\r
+- 制作所有的表盘以及lzma文件\r
+\r
+ ```\r
+ ./gen_dial_bin.sh\r
+ ```\r
+\r
+\r
+\r
+### 更新版本0110\r
+\r
+制作指定段表盘 : start ->end 根据表盘Id 进行依次制作表盘\r
+\r
+```c\r
+ 示例 ./gen_dial_bin.sh ../instance/114/ ../instance/124/ \r
+```\r
+\r
+- 效果会生成 114->124 一共11个表盘\r