save.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import os
  2. from PIL import Image
  3. from abc import abstractmethod
  4. from .rendering.gimp_render import gimp_render
  5. from .utils import Context
  6. class FormatNotSupportedException(Exception):
  7. def __init__(self, fmt: str):
  8. super().__init__(f'Format {fmt} is not supported.')
  9. OUTPUT_FORMATS = {}
  10. def register_format(format_cls):
  11. for fmt in format_cls.SUPPORTED_FORMATS:
  12. if fmt in OUTPUT_FORMATS:
  13. raise Exception(f'Tried to register multiple ExportFormats for "{fmt}"')
  14. OUTPUT_FORMATS[fmt] = format_cls()
  15. return format_cls
  16. class ExportFormat():
  17. SUPPORTED_FORMATS = []
  18. # Subclasses will be auto registered
  19. def __init_subclass__(cls, **kwargs):
  20. super().__init_subclass__(**kwargs)
  21. register_format(cls)
  22. def save(self, result: Image.Image, dest: str, ctx: Context):
  23. self._save(result, dest, ctx)
  24. @abstractmethod
  25. def _save(self, result: Image.Image, dest: str, ctx: Context):
  26. pass
  27. def save_result(result: Image.Image, dest: str, ctx: Context):
  28. _, ext = os.path.splitext(dest)
  29. ext = ext[1:]
  30. if ext not in OUTPUT_FORMATS:
  31. raise FormatNotSupportedException(ext)
  32. format_handler: ExportFormat = OUTPUT_FORMATS[ext]
  33. format_handler.save(result, dest, ctx)
  34. # -- Format Implementations
  35. class ImageFormat(ExportFormat):
  36. SUPPORTED_FORMATS = ['png', 'webp']
  37. def _save(self, result: Image.Image, dest: str, ctx: Context):
  38. result.save(dest)
  39. class JPGFormat(ExportFormat):
  40. SUPPORTED_FORMATS = ['jpg', 'jpeg']
  41. def _save(self, result: Image.Image, dest: str, ctx: Context):
  42. result = result.convert('RGB')
  43. # Certain versions of PIL only support JPEG but not JPG
  44. result.save(dest, quality=ctx.save_quality, format='JPEG')
  45. class GIMPFormat(ExportFormat):
  46. SUPPORTED_FORMATS = ['xcf', 'psd', 'pdf']
  47. def _save(self, result: Image.Image, dest: str, ctx: Context):
  48. gimp_render(dest, ctx)
  49. # class KraFormat(ExportFormat):
  50. # SUPPORTED_FORMATS = ['kra']
  51. # def _save(self, result: Image.Image, dest: str, ctx: Context):
  52. # ...
  53. # class SvgFormat(TranslationExportFormat):
  54. # SUPPORTED_FORMATS = ['svg']