Martin Renold a écrit :
On Sun, Jul 26, 2009 at 05:32:56PM -0500, Eric Honaker wrote:
[...]
If you really need to fix such a thing, copy the layer, paste into GIMP,
split it there, copy/paste both layers back. Or edit the .ora with Krita.
Gimp doesn't support system clipboard past. After some test you can only
copy from gimp to system clipboard
Save to multiple png and under gimp open as layers is a good workaround
It can be really frustrating to realize you just spent 5 minutes painting
on the wrong layer, and the only options you have are to accept it, or
delete and to it again.
Just made the same error today.
The undo good enough for this, but that's sad to lost work.
You can export file in muliplepng and now, with this new patch reimport
them.
There are some cleaning to do on this patch too I suppose. I keep the
same shortcut than gimp (ctrl+alt+O)
You can then copy/paste some part in gimp or other application.
I had to resynchronise the upper layer on gimp in this case, as it's
hand drawed and scanned and mypaint still doesn't support multiply.
My trick was to first degrade slightly my scan by doing : add layer mask
using grey level + inverse and apply mask on the picture and then copy
paste to mypaint to painting it. I would in this piece keep the black
draw to keep a comic strip like atmosphere, not a true painting.
http://popolon.online.fr/mypaint/toits_paris2.jpg
The frame layer could still help to be sure to keep a good frame format.
diff --git a/gui/drawwindow.py b/gui/drawwindow.py
index 9e49c1c..808885b 100644
--- a/gui/drawwindow.py
+++ b/gui/drawwindow.py
@@ -76,7 +76,7 @@ class Window(gtk.Window):
#filename is a property so that all changes will update the title
self.filename = None
-
+ self.filenames = []
self.eraser_mode_radius_change = 3*(0.3) # can go back to exact original with brush_smaller_cb()
self.eraser_mode_original_radius = None
@@ -91,6 +91,15 @@ class Window(gtk.Window):
self.set_title("MyPaint")
filename = property(get_filename, set_filename)
+ def get_filenames(self):
+ return self.filenames
+
+ # Something goes wrong with this, my knowledge in python is too low for now
+ #def set_filenames(self,*list):
+ # self.set_filename(list[0])
+ # self.filenames = list[:]
+ #filenames = property(get_filenames, set_filenames)
+
def create_ui(self):
ag = self.action_group = gtk.ActionGroup('WindowActions')
# FIXME: this xml menu only creates unneeded information duplication, I think.
@@ -100,6 +109,7 @@ class Window(gtk.Window):
<menu action='FileMenu'>
<menuitem action='New'/>
<menuitem action='Open'/>
+ <menuitem action='OpenAsLayers' />
<menuitem action='OpenRecent'/>
<separator/>
<menuitem action='Save'/>
@@ -217,6 +227,7 @@ class Window(gtk.Window):
('FileMenu', None, 'File'),
('New', None, 'New', '<control>N', None, self.new_cb),
('Open', None, 'Open...', '<control>O', None, self.open_cb),
+ ('OpenAsLayers', None, 'Open as layers', '<control><alt>O', None, self.open_multifile_cb),
('OpenRecent', None, 'Open Recent', 'F3', None, self.open_recent_cb),
('Save', None, 'Save', '<control>S', None, self.save_cb),
('SaveAs', None, 'Save As...', '<control><shift>S', None, self.save_as_cb),
@@ -739,6 +750,24 @@ class Window(gtk.Window):
self.reset_view_cb(None)
self.tdw.recenter_document()
+ def open_multifile(self, filenames):
+ filenames.reverse() # to match layers order from bottom to top
+ try:
+ self.doc.load_multifile(filenames)
+ except document.SaveLoadError, e:
+ d = gtk.MessageDialog(self, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)
+ d.set_markup(str(e))
+ d.run()
+ d.destroy()
+ else:
+ self.filename = os.path.abspath(filenames[0])
+ self.filenames = filenames[:]
+ for i, fname in enumerate(filenames):
+ self.filenames[i] = os.path.abspath(fname)
+ print 'Loaded from', self.filenames[0]
+ self.reset_view_cb(None)
+ self.tdw.recenter_document()
+
@with_wait_cursor
def save_file(self, filename, **options):
try:
@@ -833,6 +862,37 @@ class Window(gtk.Window):
else:
self.save_file(self.filename)
+ def open_multifile_cb(self, action):
+ if not self.confirm_destructive_action():
+ return
+ dialog = gtk.FileChooserDialog("Open..", self,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ dialog.set_select_multiple(True);
+ dialog.set_default_response(gtk.RESPONSE_OK)
+
+ filters = [ #name, patterns
+ ("All Recognized Formats", ("*.png", "*.jpg", "*.jpeg")),
+ ("PNG (*.png)", ("*.png",)),
+ ("JPEG (*.jpg; *.jpeg)", ("*.jpg", "*.jpeg")),
+ ]
+ for name, patterns in filters:
+ f = gtk.FileFilter()
+ f.set_name(name)
+ for p in patterns:
+ f.add_pattern(p)
+ dialog.add_filter(f)
+
+ if self.filename:
+ dialog.set_filename(self.filename)
+ try:
+ if dialog.run() == gtk.RESPONSE_OK:
+ self.open_multifile(dialog.get_filenames())
+ finally:
+ dialog.destroy()
+
+
def init_save_dialog(self):
dialog = gtk.FileChooserDialog("Save..", self,
diff --git a/lib/document.py b/lib/document.py
index 83d6ebc..efe649b 100644
--- a/lib/document.py
+++ b/lib/document.py
@@ -255,6 +255,19 @@ class Document():
self.command_stack.clear()
self.unsaved_painting_time = 0.0
+ def load_multifile(self, filenames):
+ for i, filename in enumerate(filenames):
+ if not os.path.isfile(filename):
+ raise SaveLoadError, 'File does not exist: ' + repr(filename)
+ if not os.access(filename,os.R_OK):
+ raise SaveLoadError, 'You do not have the necessary permissions to open file: ' + repr(fname)
+ trash, ext = os.path.splitext(filenames[0])
+ ext = ext.lower().replace('.', '')
+ load = getattr(self, 'load_multifile_' + ext, self.unsupported)
+ load(filenames)
+ self.command_stack.clear()
+ self.unsaved_painting_time = 0.0
+
def unsupported(self, filename):
raise SaveLoadError, 'Unknown file format extension: ' + repr(filename)
@@ -288,6 +301,26 @@ class Document():
def load_png(self, filename):
self.load_from_pixbuf(gdk.pixbuf_new_from_file(filename))
+ def load_multifile_png(self, filenames):
+ self.clear() # this leaves one empty layer
+
+ for filename in filenames:
+ pixbuf = gdk.pixbuf_new_from_file(filename)
+ self.add_layer(insert_idx=0)
+ last_pixbuf = pixbuf
+ t1 = time.time()
+ self.load_layer_from_pixbuf(pixbuf, 0, 0)
+ #self.layers[0].opacity = helpers.clamp(1.0, 0.0, 1.0)
+ print ' %.3fs converting pixbuf to layer format' % (time.time() - t1)
+
+ if len(self.layers) > 1:
+ # remove the still present initial empty top layer
+ self.select_layer(len(self.layers)-1)
+ self.remove_layer()
+ # this leaves the topmost layer selected
+
+
+
def load_jpg(self, filename):
self.load_from_pixbuf(gdk.pixbuf_new_from_file(filename))
load_jpeg = load_jpg
_______________________________________________
Mypaint-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/mypaint-discuss