v1
This commit is contained in:
105
.gitignore
vendored
105
.gitignore
vendored
@@ -114,3 +114,108 @@ dmypy.json
|
|||||||
|
|
||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
|
### PyCharm ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### PyCharm Patch ###
|
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||||
|
|
||||||
|
# *.iml
|
||||||
|
# modules.xml
|
||||||
|
# .idea/misc.xml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||||
|
.idea/**/sonarlint/
|
||||||
|
|
||||||
|
# SonarQube Plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||||
|
.idea/**/sonarIssues.xml
|
||||||
|
|
||||||
|
# Markdown Navigator plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||||
|
.idea/**/markdown-navigator.xml
|
||||||
|
.idea/**/markdown-navigator-enh.xml
|
||||||
|
.idea/**/markdown-navigator/
|
||||||
|
|
||||||
|
# Cache file creation bug
|
||||||
|
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||||
|
.idea/$CACHE_FILE$
|
||||||
|
|
||||||
|
# CodeStream plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||||
|
.idea/codestream.xml
|
||||||
|
|
||||||
|
/output
|
||||||
2
.idea/.gitignore
generated
vendored
Normal file
2
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/workspace.xml
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
10
.idea/live-a-png.iml
generated
Normal file
10
.idea/live-a-png.iml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (live-a-png)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/live-a-png.iml" filepath="$PROJECT_DIR$/.idea/live-a-png.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -21,6 +21,7 @@ Edit those files to populate the correct values.
|
|||||||
|
|
||||||
## Run the code
|
## Run the code
|
||||||
|
|
||||||
|
Edit `main.py` to set the directory of the extracted asset bundles.
|
||||||
Run `main.py` in the terminal to start the application.
|
Run `main.py` in the terminal to start the application.
|
||||||
|
|
||||||
## Development: Making changes
|
## Development: Making changes
|
||||||
|
|||||||
44
image_assembler.py
Normal file
44
image_assembler.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import math
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
|
class ImageAssembler:
|
||||||
|
def __init__(self, metadata, atlas: Image, cell_size: int, padding: int):
|
||||||
|
self.atlas = atlas
|
||||||
|
self.atlas_width_cells = int(atlas.size[0] / cell_size)
|
||||||
|
self.atlas_height_cells = int(atlas.size[1] / cell_size)
|
||||||
|
|
||||||
|
self.cell_size = cell_size
|
||||||
|
self.padding = padding
|
||||||
|
self.metadata = metadata
|
||||||
|
|
||||||
|
self.output = Image.new('RGBA', (metadata['width'], metadata['height']), (255, 255, 255, 0))
|
||||||
|
|
||||||
|
# TODO double check this logic
|
||||||
|
self.output_width_cells = math.ceil(float(metadata['width']) / cell_size)
|
||||||
|
|
||||||
|
def atlas_get_cell(self, cell_no: int):
|
||||||
|
cell_x_pos = cell_no % self.atlas_width_cells
|
||||||
|
cell_y_pos = self.atlas_height_cells - math.floor(cell_no / self.atlas_width_cells) - 1 # From top
|
||||||
|
return self.atlas.crop((
|
||||||
|
cell_x_pos * self.cell_size,
|
||||||
|
cell_y_pos * self.cell_size,
|
||||||
|
(cell_x_pos + 1) * self.cell_size,
|
||||||
|
(cell_y_pos + 1) * self.cell_size
|
||||||
|
))
|
||||||
|
|
||||||
|
def paint(self):
|
||||||
|
for i in range(len(self.metadata['cellIndexList'])):
|
||||||
|
source_cell_number = self.metadata['cellIndexList'][i]
|
||||||
|
source_cell = self.atlas_get_cell(source_cell_number)
|
||||||
|
|
||||||
|
output_x_pos = i % self.output_width_cells
|
||||||
|
output_y_pos = math.floor(i / self.output_width_cells) # From bottom
|
||||||
|
self.output.paste(source_cell, (
|
||||||
|
output_x_pos * (self.cell_size - (2*self.padding)),
|
||||||
|
self.output.size[1] - self.cell_size - (output_y_pos * (self.cell_size - (2*self.padding)))
|
||||||
|
))
|
||||||
|
|
||||||
|
def get_output(self):
|
||||||
|
return self.output
|
||||||
|
|
||||||
31
main.py
Normal file
31
main.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import json
|
||||||
|
from os import PathLike
|
||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
from image_assembler import ImageAssembler
|
||||||
|
|
||||||
|
json_dir = Path('C:\\extracts\\MonoBehaviour')
|
||||||
|
atlas_dir = Path('C:\\extracts\\Texture2D')
|
||||||
|
output_dir = Path('./output')
|
||||||
|
|
||||||
|
|
||||||
|
def assemble_json(json_file: PathLike):
|
||||||
|
with open(json_file) as f:
|
||||||
|
metadata = json.load(f)
|
||||||
|
|
||||||
|
for image in metadata['textureDataList']:
|
||||||
|
# TODO try-catch Image.open
|
||||||
|
atlas = Image.open(atlas_dir / (image['atlasName'] + '.png'))
|
||||||
|
assembler = ImageAssembler(image, atlas, metadata['cellSize'], metadata['padding'])
|
||||||
|
assembler.paint()
|
||||||
|
output = assembler.get_output()
|
||||||
|
|
||||||
|
output.save(output_dir / (image['name'] + '.png'), 'PNG')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
for item in json_dir.iterdir():
|
||||||
|
if item.is_file() and (str(item)).endswith('.json'):
|
||||||
|
print(item)
|
||||||
|
assemble_json(item)
|
||||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Pillow==7.2.0
|
||||||
Reference in New Issue
Block a user