def save_ora(self, filename, options=None, **kwargs): logger.info('save_ora: %r (%r, %r)', filename, options, kwargs) t0 = time.time() tempdir = tempfile.mkdtemp('mypaint') if not isinstance(tempdir, unicode): tempdir = tempdir.decode(sys.getfilesystemencoding()) # use .tmp extension, so we don't overwrite a valid file if there is an exception z = zipfile.ZipFile(filename + '.tmpsave', 'w', compression=zipfile.ZIP_STORED) # work around a permission bug in the zipfile library: http://bugs.python.org/issue3394 def write_file_str(filename, data): zi = zipfile.ZipInfo(filename) zi.external_attr = 0100644 << 16 z.writestr(zi, data) write_file_str('mimetype', 'image/openraster') # must be the first file image = ET.Element('image') stack = ET.SubElement(image, 'stack') x0, y0, w0, h0 = self.get_effective_bbox() a = image.attrib a['w'] = str(w0) a['h'] = str(h0) def store_pixbuf(pixbuf, name): tmp = join(tempdir, 'tmp.png') t1 = time.time() pixbuf.savev(tmp, 'png', [], []) logger.debug('%.3fs pixbuf saving %s', time.time() - t1, name) z.write(tmp, name) os.remove(tmp) def store_surface(surface, name, rect=[]): tmp = join(tempdir, 'tmp.png') t1 = time.time() surface.save_as_png(tmp, *rect, **kwargs) logger.debug('%.3fs surface saving %s', time.time() - t1, name) z.write(tmp, name) os.remove(tmp) def add_layer(x, y, opac, surface, name, layer_name, visible=True, locked=False, selected=False, compositeop=DEFAULT_COMPOSITE_OP, rect=[]): layer = ET.Element('layer') stack.append(layer) store_surface(surface, name, rect) a = layer.attrib if layer_name: a['name'] = layer_name a['src'] = name a['x'] = str(x) a['y'] = str(y) a['opacity'] = str(opac) if compositeop not in VALID_COMPOSITE_OPS: compositeop = DEFAULT_COMPOSITE_OP a['composite-op'] = compositeop if visible: a['visibility'] = 'visible' else: a['visibility'] = 'hidden' if locked: a['edit-locked'] = 'true' if selected: a['selected'] = 'true' return layer for idx, l in enumerate(reversed(self.layers)): if l.is_empty(): continue opac = l.opacity x, y, w, h = l.get_bbox() sel = (idx == self.layer_idx) el = add_layer(x - x0, y - y0, opac, l._surface, 'data/layer%03d.png' % idx, l.name, l.visible, locked=l.locked, selected=sel, compositeop=l.compositeop, rect=(x, y, w, h)) # strokemap sio = StringIO() l.save_strokemap_to_file(sio, -x, -y) data = sio.getvalue() sio.close() name = 'data/layer%03d_strokemap.dat' % idx el.attrib['mypaint_strokemap_v2'] = name write_file_str(name, data) # save background as layer (solid color or tiled) bg = self.background # save as fully rendered layer x, y, w, h = self.get_bbox() l = add_layer(x - x0, y - y0, 1.0, bg, 'data/background.png', 'background', locked=True, selected=False, compositeop=DEFAULT_COMPOSITE_OP, rect=(x, y, w, h)) x, y, w, h = bg.get_bbox() # save as single pattern (with corrected origin) store_surface(bg, 'data/background_tile.png', rect=(x + x0, y + y0, w, h)) l.attrib['background_tile'] = 'data/background_tile.png' # preview (256x256) t2 = time.time() logger.debug('starting to render full image for thumbnail...') thumbnail_pixbuf = self.render_thumbnail() store_pixbuf(thumbnail_pixbuf, 'Thumbnails/thumbnail.png') logger.debug('total %.3fs spent on thumbnail', time.time() - t2) helpers.indent_etree(image) xml = ET.tostring(image, encoding='UTF-8') write_file_str('stack.xml', xml) z.close() os.rmdir(tempdir) if os.path.exists(filename): os.remove(filename) # windows needs that os.rename(filename + '.tmpsave', filename) logger.info('%.3fs save_ora total', time.time() - t0) return thumbnail_pixbuf
def save_ora(self, filename, options=None, **kwargs): """Saves OpenRaster data to a file""" logger.info('save_ora: %r (%r, %r)', filename, options, kwargs) t0 = time.time() tempdir = tempfile.mkdtemp('mypaint') if not isinstance(tempdir, unicode): tempdir = tempdir.decode(sys.getfilesystemencoding()) # Use .tmpsave extension, so we don't overwrite a valid file if there # is an exception orazip = zipfile.ZipFile(filename + '.tmpsave', 'w', compression=zipfile.ZIP_STORED) # work around a permission bug in the zipfile library: # http://bugs.python.org/issue3394 def write_file_str(filename, data): zi = zipfile.ZipInfo(filename) zi.external_attr = 0100644 << 16 orazip.writestr(zi, data) write_file_str('mimetype', 'image/openraster') # must be the first file image = ET.Element('image') effective_bbox = self.get_effective_bbox() x0, y0, w0, h0 = effective_bbox image.attrib['w'] = str(w0) image.attrib['h'] = str(h0) # Update the initially-selected flag on all layers layers = self.layer_stack for s_path, s_layer in layers.deepenumerate(): selected = (s_path == layers.current_path) s_layer.initially_selected = selected # Save the layer stack canvas_bbox = tuple(self.get_bbox()) frame_bbox = tuple(effective_bbox) root_stack_path = () root_stack_elem = self.layer_stack.save_to_openraster( orazip, tempdir, root_stack_path, canvas_bbox, frame_bbox, **kwargs ) image.append(root_stack_elem) # Resolution info if self._xres and self._yres: image.attrib["xres"] = str(self._xres) image.attrib["yres"] = str(self._yres) # Version declaration image.attrib["version"] = "0.0.4-pre.1" ani_data = self.ani.xsheet_as_str() write_file_str('animation.xsheet', ani_data) # Thumbnail preview (256x256) thumbnail = layers.render_thumbnail(frame_bbox) tmpfile = join(tempdir, 'tmp.png') thumbnail.savev(tmpfile, 'png', [], []) orazip.write(tmpfile, 'Thumbnails/thumbnail.png') os.remove(tmpfile) # Save fully rendered image too tmpfile = os.path.join(tempdir, "mergedimage.png") self.layer_stack.save_as_png( tmpfile, *frame_bbox, alpha=False, background=True, **kwargs ) orazip.write(tmpfile, 'mergedimage.png') os.remove(tmpfile) # Prettification helpers.indent_etree(image) xml = ET.tostring(image, encoding='UTF-8') # Finalize write_file_str('stack.xml', xml) orazip.close() os.rmdir(tempdir) if os.path.exists(filename): os.remove(filename) # windows needs that os.rename(filename + '.tmpsave', filename) logger.info('%.3fs save_ora total', time.time() - t0) return thumbnail
def save_ora(self, filename, options=None, **kwargs): print 'save_ora:' t0 = time.time() tempdir = tempfile.mkdtemp('mypaint') if not isinstance(tempdir, unicode): tempdir = tempdir.decode(sys.getfilesystemencoding()) # use .tmp extension, so we don't overwrite a valid file if there is an exception z = zipfile.ZipFile(filename + '.tmpsave', 'w', compression=zipfile.ZIP_STORED) # work around a permission bug in the zipfile library: http://bugs.python.org/issue3394 def write_file_str(filename, data): zi = zipfile.ZipInfo(filename) zi.external_attr = 0100644 << 16 z.writestr(zi, data) write_file_str('mimetype', 'image/openraster') # must be the first file image = ET.Element('image') stack = ET.SubElement(image, 'stack') x0, y0, w0, h0 = self.get_effective_bbox() a = image.attrib a['w'] = str(w0) a['h'] = str(h0) def store_pixbuf(pixbuf, name): tmp = join(tempdir, 'tmp.png') t1 = time.time() pixbuf.savev(tmp, 'png', [], []) print ' %.3fs pixbuf saving %s' % (time.time() - t1, name) z.write(tmp, name) os.remove(tmp) def store_surface(surface, name, rect=[]): tmp = join(tempdir, 'tmp.png') t1 = time.time() surface.save_as_png(tmp, *rect, **kwargs) print ' %.3fs surface saving %s' % (time.time() - t1, name) z.write(tmp, name) os.remove(tmp) def add_layer(x, y, opac, surface, name, layer_name, visible=True, locked=False, selected=False, compositeop=DEFAULT_COMPOSITE_OP, rect=[]): layer = ET.Element('layer') stack.append(layer) store_surface(surface, name, rect) a = layer.attrib if layer_name: a['name'] = layer_name a['src'] = name a['x'] = str(x) a['y'] = str(y) a['opacity'] = str(opac) if compositeop not in VALID_COMPOSITE_OPS: compositeop = DEFAULT_COMPOSITE_OP a['composite-op'] = compositeop if visible: a['visibility'] = 'visible' else: a['visibility'] = 'hidden' if locked: a['edit-locked'] = 'true' if selected: a['selected'] = 'true' return layer for idx, l in enumerate(reversed(self.layers)): if l.is_empty(): continue opac = l.opacity x, y, w, h = l.get_bbox() sel = (idx == self.layer_idx) el = add_layer(x-x0, y-y0, opac, l._surface, 'data/layer%03d.png' % idx, l.name, l.visible, locked=l.locked, selected=sel, compositeop=l.compositeop, rect=(x, y, w, h)) # strokemap sio = StringIO() l.save_strokemap_to_file(sio, -x, -y) data = sio.getvalue(); sio.close() name = 'data/layer%03d_strokemap.dat' % idx el.attrib['mypaint_strokemap_v2'] = name write_file_str(name, data) ani_data = self.ani.xsheet_as_str() write_file_str('animation.xsheet', ani_data) # save background as layer (solid color or tiled) bg = self.background # save as fully rendered layer x, y, w, h = self.get_bbox() l = add_layer(x-x0, y-y0, 1.0, bg, 'data/background.png', 'background', locked=True, selected=False, compositeop=DEFAULT_COMPOSITE_OP, rect=(x,y,w,h)) x, y, w, h = bg.get_bbox() # save as single pattern (with corrected origin) store_surface(bg, 'data/background_tile.png', rect=(x+x0, y+y0, w, h)) l.attrib['background_tile'] = 'data/background_tile.png' # preview (256x256) t2 = time.time() print ' starting to render full image for thumbnail...' thumbnail_pixbuf = self.render_thumbnail() store_pixbuf(thumbnail_pixbuf, 'Thumbnails/thumbnail.png') print ' total %.3fs spent on thumbnail' % (time.time() - t2) helpers.indent_etree(image) xml = ET.tostring(image, encoding='UTF-8') write_file_str('stack.xml', xml) z.close() os.rmdir(tempdir) if os.path.exists(filename): os.remove(filename) # windows needs that os.rename(filename + '.tmpsave', filename) print '%.3fs save_ora total' % (time.time() - t0) return thumbnail_pixbuf
def save_ora(self, filename, options=None, **kwargs): """Saves OpenRaster data to a file""" logger.info('save_ora: %r (%r, %r)', filename, options, kwargs) t0 = time.time() tempdir = tempfile.mkdtemp('mypaint') if not isinstance(tempdir, unicode): tempdir = tempdir.decode(sys.getfilesystemencoding()) orazip = zipfile.ZipFile(filename, 'w', compression=zipfile.ZIP_STORED) # work around a permission bug in the zipfile library: # http://bugs.python.org/issue3394 def write_file_str(filename, data): zi = zipfile.ZipInfo(filename) zi.external_attr = 0100644 << 16 orazip.writestr(zi, data) write_file_str('mimetype', 'image/openraster') # must be the first file image = ET.Element('image') effective_bbox = self.get_effective_bbox() x0, y0, w0, h0 = effective_bbox image.attrib['w'] = str(w0) image.attrib['h'] = str(h0) # Update the initially-selected flag on all layers layers = self.layer_stack for s_path, s_layer in layers.walk(): selected = (s_path == layers.current_path) s_layer.initially_selected = selected # Save the layer stack canvas_bbox = tuple(self.get_bbox()) frame_bbox = tuple(effective_bbox) root_stack_path = () root_stack_elem = self.layer_stack.save_to_openraster( orazip, tempdir, root_stack_path, canvas_bbox, frame_bbox, **kwargs) image.append(root_stack_elem) # Resolution info if self._xres and self._yres: image.attrib["xres"] = str(self._xres) image.attrib["yres"] = str(self._yres) # OpenRaster version declaration image.attrib["version"] = "0.0.4-pre.1" # Thumbnail preview (256x256) thumbnail = layers.render_thumbnail(frame_bbox) tmpfile = join(tempdir, 'tmp.png') lib.pixbuf.save(thumbnail, tmpfile, 'png') orazip.write(tmpfile, 'Thumbnails/thumbnail.png') os.remove(tmpfile) # Save fully rendered image too tmpfile = os.path.join(tempdir, "mergedimage.png") self.layer_stack.save_as_png(tmpfile, *frame_bbox, alpha=False, background=True, **kwargs) orazip.write(tmpfile, 'mergedimage.png') os.remove(tmpfile) # Prettification helpers.indent_etree(image) xml = ET.tostring(image, encoding='UTF-8') # Finalize write_file_str('stack.xml', xml) orazip.close() os.rmdir(tempdir) logger.info('%.3fs save_ora total', time.time() - t0) return thumbnail