Bug: Write bug causing the layers to be inverted
Hello! Hope you are well
Description
The last couple of commits (prior to 15/06/2020) to layeredimage have exhibited a bug causing written ora files to have layers inverted. My first port of call was to invert the LayeredImage groups and layers when writing to ora using this library. That didn't work and so I monkey patched the code as shown below. I want to contribute this back as unless I am misusing the add_layer function I think this will affect this project
External programs tested in
Tested ora images in Gimp and Krita (both newest release as of writing)
Example program
Use layeredimage == 2020.6.4 (fixed in 2020.6.5)
""" example program to convert layered images to ora """
from os.path import isfile, join
from os import listdir
from pathlib import Path
import layeredimage.io
THISDIR = str(Path(__file__).resolve().parent)
files = [
join(THISDIR, file) for file in listdir(THISDIR)
if isfile(join(THISDIR, file))]
for file in files:
try:
layeredimage.io.saveLayerImage(file + ".ora", layeredimage.io.openLayerImage(file))
except ValueError:
pass
Environment Info
pyora==0.*,>=0.3.8
Python 3.8
Windows 10 1909
Proposed fix
Monkey patch
def addElem_fix(self, tag, parent_elem, name, z_index=1, offsets=(0, 0,), opacity=1.0,
visible=True, composite_op="svg:src-over", **kwargs):
""" Patch the Project._add_elem function from pyora 0.3.8 with a newer version
This snippet is MIT License Copyright (c) 2019 Paul Jewell
"""
import uuid
from xml.etree.ElementTree import Element
if tag == 'stack' and 'isolated' not in kwargs:
kwargs['isolated'] = True
if 'uuid' not in kwargs or kwargs['uuid'] is None:
self._generated_uuids = True
kwargs['uuid'] = str(uuid.uuid4())
newElem = Element(tag, {'name': name, 'x': str(offsets[0]), 'y': str(offsets[1]),
'visibility': 'visible' if visible else 'hidden',
'opacity': str(opacity), 'composite-op': composite_op,
**{k: str(v) for k, v in kwargs.items() if v is not None}})
parent_elem.insert(0, newElem)
return newElem
Source compatible
Hopefully the following snippet is compatible with and takes the extra considerations of the source implementation into account
def _add_elem(self, tag, parent_elem, name, z_index=1, offsets=(0, 0,), opacity=1.0,
visible=True, composite_op="svg:src-over", **kwargs):
import uuid
from xml.etree.ElementTree import Element
if tag == 'stack' and 'isolated' not in kwargs:
kwargs['isolated'] = True
if 'uuid' not in kwargs or kwargs['uuid'] is None:
self._generated_uuids = True
kwargs['uuid'] = str(uuid.uuid4())
new_elem = Element(tag, {'name': name, 'x': str(offsets[0]), 'y': str(offsets[1]),
'visibility': 'visible' if visible else 'hidden',
'opacity': str(opacity), 'composite-op': composite_op,
**{k: str(v) for k, v in kwargs.items() if v is not None}})
parent_elem.insert(max(0, 0 - (z_index - 1)), new_elem) #? We don't want to insert before 0
return new_elem
Thank you for your time and hope this helps :)