/gtk/prep-images

To get this branch, use:
bzr branch http://bzr.ed.am/gtk/prep-images

« back to all changes in this revision

Viewing changes to lib/prep_images/main_window.py

  • Committer: Tim Marston
  • Date: 2013-07-17 22:56:36 UTC
  • Revision ID: tim@ed.am-20130717225636-on2as6cto9js0cpr
set version to development version

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#
3
3
# Copyright (C) 2011 Tim Marston <edam@waxworlds.org>
4
4
#
5
 
# This file is part of add-copyright-to-images (hereafter referred to as "this
6
 
# program").
7
 
# See http://www.waxworlds.org/edam/software/add-copyright-to-images for more
 
5
# This file is part of prep-images (hereafter referred to as "this program").
 
6
# See http://www.waxworlds.org/edam/software/gtk/prep-images for more
8
7
# information.
9
8
#
10
9
# This program is free software: you can redistribute it and/or modify
11
 
# it under the terms of the GNU Lesser General Public License as published
12
 
# by the Free Software Foundation, either version 3 of the License, or
 
10
# it under the terms of the GNU General Public License as published by
 
11
# the Free Software Foundation, either version 3 of the License, or
13
12
# (at your option) any later version.
14
13
#
15
14
# This program is distributed in the hope that it will be useful,
16
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
# GNU Lesser General Public License for more details.
 
17
# GNU General Public License for more details.
19
18
#
20
 
# You should have received a copy of the GNU Lesser General Public License
 
19
# You should have received a copy of the GNU General Public License
21
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
21
 
23
22
 
54
53
                # work out the initial size of the drawing area so that the greatest of
55
54
                # the two dimensions is 450px
56
55
                scale = min( \
57
 
                                float( self.DRAWING_AREA_INIT_WIDTH ) / self.pic.get_width(), \
58
 
                                float( self.DRAWING_AREA_INIT_HEIGHT ) / self.pic.get_height() )
 
56
                        float( self.DRAWING_AREA_INIT_WIDTH ) / self.pic.get_width(), \
 
57
                        float( self.DRAWING_AREA_INIT_HEIGHT ) / self.pic.get_height() )
59
58
                init_width = int( round( scale * self.pic.get_width() ) )
60
59
                init_height = int( round( scale * self.pic.get_height() ) )
61
60
 
74
73
                self.drawing_area = gtk.DrawingArea()
75
74
                self.drawing_area.set_size_request( init_width, init_height )
76
75
                self.drawing_area.add_events( gtk.gdk.POINTER_MOTION_MASK | \
77
 
                                gtk.gdk.POINTER_MOTION_HINT_MASK | \
78
 
                                gtk.gdk.BUTTON_PRESS_MASK )
 
76
                        gtk.gdk.POINTER_MOTION_HINT_MASK | \
 
77
                        gtk.gdk.BUTTON_PRESS_MASK )
79
78
                self.drawing_area.connect( "configure_event", \
80
 
                                self.drawing_area_configure_event )
 
79
                        self.drawing_area_configure_event )
81
80
                self.drawing_area.connect( "expose_event", \
82
 
                                self.drawing_area_expose_event )
 
81
                        self.drawing_area_expose_event )
83
82
                self.drawing_area.connect( "motion_notify_event", \
84
 
                                self.motion_notify_event )
 
83
                        self.motion_notify_event )
85
84
                self.drawing_area.connect( "button_press_event", \
86
 
                                self.drawing_area_button_press_event )
 
85
                        self.drawing_area_button_press_event )
87
86
                vbox.pack_start( self.drawing_area, True, True, 0 )
88
87
 
89
88
                # create buttons
101
100
                left_button_box.pack_start( prefs_button, True, True, 0 )
102
101
                cancel_button = gtk.Button( stock = gtk.STOCK_CANCEL )
103
102
                cancel_button.connect_object( "clicked", gtk.Widget.destroy, \
104
 
                                self.window )
 
103
                        self.window )
105
104
                button_box.pack_end( cancel_button, True, True, 0 )
106
105
                self.ok_button = gtk.Button( stock = gtk.STOCK_APPLY )
107
106
                self.ok_button.connect( "clicked", self.ok_button_pressed )
117
116
                self.load_copyright_image()
118
117
 
119
118
        def load_main_image( self ):
 
119
 
120
120
                # load image file
121
121
                try:
122
122
                        self.pic = gtk.gdk.pixbuf_new_from_file( self.filename )
123
123
                except gobject.GError as e:
124
124
                        dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, \
125
 
                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, e.message )
 
125
                                gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, e.message )
126
126
                        dialog.run()
127
127
                        dialog.destroy()
128
128
                        exit( 1 )
130
130
                # scale it
131
131
                if self.prefs.resize:
132
132
                        scale = min( \
133
 
                                        float( self.prefs.resize_width ) / self.pic.get_width(), \
134
 
                                        float( self.prefs.resize_height ) / self.pic.get_height() )
 
133
                                float( self.prefs.resize_width ) / self.pic.get_width(), \
 
134
                                float( self.prefs.resize_height ) / self.pic.get_height() )
135
135
                        self.pic = self.pic.scale_simple( \
136
136
                                int( round( scale * self.pic.get_width() ) ), \
137
137
                                int( round( scale * self.pic.get_height() ) ), \
146
146
                # check if we've got a copyright filename set
147
147
                if self.prefs.copyright_filename == '':
148
148
                        dialog = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL, \
149
 
                                        gtk.MESSAGE_INFO, gtk.BUTTONS_OK, \
150
 
                                        "No copyright image has been set. " + \
151
 
                                        "Please set one in the Preferences." )
 
149
                                gtk.MESSAGE_INFO, gtk.BUTTONS_OK, \
 
150
                                "No copyright image has been set. " + \
 
151
                                "Please set one in the Preferences." )
152
152
                        dialog.format_secondary_text( "While this issue persists, you " + \
153
 
                                        "can not proceed with this operation" )
 
153
                                "can not proceed with this operation" )
154
154
                        dialog.run()
155
155
                        dialog.destroy()
156
156
                        return
158
158
                # load copyright overlay image file
159
159
                try:
160
160
                        self.copyright_pic = gtk.gdk.pixbuf_new_from_file( \
161
 
                                        os.path.expanduser( self.prefs.copyright_filename ) )
 
161
                                os.path.expanduser( self.prefs.copyright_filename ) )
162
162
                except gobject.GError as e:
163
163
                        dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, \
164
 
                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
165
 
                                        "Unable to load copyright overlay image: " + \
166
 
                                        e.message )
 
164
                                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
 
165
                                "Unable to load copyright overlay image: " + \
 
166
                                e.message )
167
167
                        dialog.format_secondary_text( "While this issue persists, you " + \
168
 
                                        "can not proceed with this operation" )
 
168
                                "can not proceed with this operation" )
169
169
                        dialog.run()
170
170
                        dialog.destroy()
171
171
                        return
174
174
                if self.copyright_pic.get_width() > self.pic.get_width() or \
175
175
                                self.copyright_pic.get_height() > self.pic.get_height():
176
176
                        dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, \
177
 
                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
178
 
                                        "The copyright overlay image is larger than the photo!" )
 
177
                                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
 
178
                                "The copyright overlay image is larger than the photo!" )
179
179
                        dialog.format_secondary_text( "While this issue persists, you " + \
180
180
                                        "can not proceed with this operation" )
181
181
                        dialog.run()
200
200
                else:
201
201
                        append = self.prefs.export_append
202
202
                out_filename = self.filename[ : self.filename.rindex( '.' ) ] + \
203
 
                                append + self.filename[ self.filename.rindex( '.' ) : ]
 
203
                        append + self.filename[ self.filename.rindex( '.' ) : ]
204
204
 
205
205
                # calculate geometry
206
206
                top = 0 if self.pos.find( 'top' ) != -1 else \
207
 
                                self.pic.get_height() - self.copyright_pic.get_height()
 
207
                        self.pic.get_height() - self.copyright_pic.get_height()
208
208
                left = 0 if self.pos.find( 'left' ) != -1 else \
209
 
                                self.pic.get_width() - self.copyright_pic.get_width()
 
209
                        self.pic.get_width() - self.copyright_pic.get_width()
210
210
 
211
211
                infile = self.filename
212
212
 
213
 
                # caluclate program args
 
213
                # calculate program args
214
214
                resize_geometry = str( self.prefs.resize_width ) + "x" + \
215
 
                                str( self.prefs.resize_height )
 
215
                        str( self.prefs.resize_height )
216
216
                copyright_geometry = str( self.copyright_pic.get_width() ) + \
217
 
                                "x" + str( self.copyright_pic.get_height() ) + "+" + \
218
 
                                str( left ) + "+" + str( top )
 
217
                        "x" + str( self.copyright_pic.get_height() ) + "+" + \
 
218
                        str( left ) + "+" + str( top )
219
219
                args = [ self.IMAGEMAGICK_CONVERT_BIN, \
220
 
                                os.path.expanduser( self.prefs.copyright_filename ), \
221
 
                                "-geometry", copyright_geometry, \
222
 
                                "-compose", "screen", "-composite", \
223
 
                                out_filename ]
 
220
                        os.path.expanduser( self.prefs.copyright_filename ), \
 
221
                        "-geometry", copyright_geometry, \
 
222
                        "-compose", "src-over", "-composite", \
 
223
                        out_filename ]
224
224
                if( self.prefs.resize ):
225
225
                        args[ 1 : 1 ] = [ "(", "-resize", resize_geometry, \
226
 
                                        self.filename, ")" ]
 
226
                                self.filename, "-unsharp", "1x3+.6+.09", ")" ]
227
227
                else:
228
228
                        args[ 1 : 1 ] = [ self.filename ]
229
229
 
230
230
                # call ImageMagick to do our dirtywork
231
231
                try:
 
232
                        print "calling: " + ' '.join( args )
232
233
                        ret = call( args )
233
234
                        if ret != 0:
234
235
                                print >>sys.stderr, "ImageMagick failed, returned ", ret
243
244
                                os.rename( self.filename, self.filename + ".old" )
244
245
                        except OSError as e:
245
246
                                print >>sys.stderr, "Could not rename original image file: ", \
246
 
                                                e.strerror
 
247
                                        e.strerror
247
248
                                exit( 1 )
248
249
 
249
250
                        # move new file in-place
311
312
                        state = event.state
312
313
 
313
314
                # calculate copyright overlay pos
314
 
                pos =   ( "top" if y <= height / 2 else "bottom" ) + "-" + \
315
 
                                ( "left" if x <= width / 2 else "right" )
 
315
                pos = ( "top" if y <= height / 2 else "bottom" ) + "-" + \
 
316
                        ( "left" if x <= width / 2 else "right" )
316
317
 
317
318
                # redraw if necessary
318
319
                if getattr( self, "pos", None ) != pos:
331
332
 
332
333
                # work out minimum scale required to fit pic_orig in to the widget area
333
334
                scale = min( float( width ) / self.pic.get_width(),
334
 
                                float( height ) / self.pic.get_height() )
 
335
                        float( height ) / self.pic.get_height() )
335
336
 
336
337
                # scale the images
337
338
                self.pic_scale = self.pic.scale_simple( \
338
 
                                int( round( scale * self.pic.get_width() ) ), \
339
 
                                int( round( scale * self.pic.get_height() ) ), \
340
 
                                gtk.gdk.INTERP_BILINEAR )
 
339
                        int( round( scale * self.pic.get_width() ) ), \
 
340
                        int( round( scale * self.pic.get_height() ) ), \
 
341
                        gtk.gdk.INTERP_BILINEAR )
341
342
                if self.copyright_pic != None:
342
343
                        self.copyright_pic_scale = self.copyright_pic.scale_simple( \
343
 
                                        int( round( scale * self.copyright_pic.get_width() ) ), \
344
 
                                        int( round( scale * self.copyright_pic.get_height() ) ), \
345
 
                                        gtk.gdk.INTERP_BILINEAR )
 
344
                                int( round( scale * self.copyright_pic.get_width() ) ), \
 
345
                                int( round( scale * self.copyright_pic.get_height() ) ), \
 
346
                                gtk.gdk.INTERP_BILINEAR )
346
347
 
347
348
                # recreate the pixmap to render to the screen
348
349
                self.generate_pixmap()
351
352
                widget = self.drawing_area
352
353
                x, y, width, height = widget.get_allocation()
353
354
 
354
 
                # calculate offsets to center pic in drawing area
 
355
                # calculate offsets to centre pic in drawing area
355
356
                pre_width = ( width - self.pic_scale.get_width() ) / 2
356
357
                pre_height = ( height - self.pic_scale.get_height() ) / 2
357
358
                post_width = width - self.pic_scale.get_width() - pre_width
364
365
                pixbuf = self.pic_scale.copy()
365
366
 
366
367
                if self.copyright_pic != None and \
367
 
                                getattr( self, "copyright_pic_scale", None ) != None:
 
368
                        getattr( self, "copyright_pic_scale", None ) != None:
368
369
 
369
370
                        # work out position of copyright overlay
370
371
                        if self.pos == "top-left" or self.pos == "bottom-left":
371
372
                                x = 0
372
373
                        if self.pos == "top-right" or self.pos == "bottom-right":
373
374
                                x = self.pic_scale.get_width() - \
374
 
                                                self.copyright_pic_scale.get_width()
 
375
                                        self.copyright_pic_scale.get_width()
375
376
                        if self.pos == "top-left" or self.pos == "top-right":
376
377
                                y = 0
377
378
                        if self.pos == "bottom-left" or self.pos == "bottom-right":
378
379
                                y = self.pic_scale.get_height() - \
379
 
                                                self.copyright_pic_scale.get_height()
 
380
                                        self.copyright_pic_scale.get_height()
380
381
 
381
382
                        # draw copyright
382
383
                        self.copyright_pic_scale.composite( pixbuf, x, y, \
383
 
                                        self.copyright_pic_scale.get_width(), \
384
 
                                        self.copyright_pic_scale.get_height(), \
385
 
                                        x, y, 1, 1, gtk.gdk.INTERP_NEAREST, 255 )
 
384
                                self.copyright_pic_scale.get_width(), \
 
385
                                self.copyright_pic_scale.get_height(), \
 
386
                                x, y, 1, 1, gtk.gdk.INTERP_NEAREST, 255 )
386
387
 
387
 
                # draw composit pixbuf to the off-screen pixmap
 
388
                # draw composite pixbuf to the off-screen pixmap
388
389
                self.pixmap.draw_pixbuf( widget.get_style().white_gc, \
389
 
                                pixbuf, 0, 0, pre_width, pre_height, \
390
 
                                pixbuf.get_width(), pixbuf.get_height() )
 
390
                        pixbuf, 0, 0, pre_width, pre_height, \
 
391
                        pixbuf.get_width(), pixbuf.get_height() )
391
392
 
392
 
                # draw black rectangles if the pic is being centered
 
393
                # draw black rectangles if the pic is being centred
393
394
                if pre_width > 0 or pre_height > 0:
394
395
                        self.pixmap.draw_rectangle( widget.get_style().black_gc, True, \
395
 
                                        0, 0, \
396
 
                                        pre_width if pre_width > 0 else width, \
397
 
                                        pre_height if pre_height > 0 else height )
 
396
                                0, 0, \
 
397
                                pre_width if pre_width > 0 else width, \
 
398
                                pre_height if pre_height > 0 else height )
398
399
                if post_width > 0 or post_height > 0:
399
400
                        self.pixmap.draw_rectangle( widget.get_style().black_gc, True, \
400
 
                                        width - post_width if post_width > 0 else 0, \
401
 
                                        height - post_height if post_height > 0 else 0, \
402
 
                                        post_width if post_width > 0 else width, \
403
 
                                        post_height if post_height > 0 else height )
 
401
                                width - post_width if post_width > 0 else 0, \
 
402
                                height - post_height if post_height > 0 else 0, \
 
403
                                post_width if post_width > 0 else width, \
 
404
                                post_height if post_height > 0 else height )
404
405
 
405
406
        def move_pos( self, tok_from, tok_to ):
 
407
 
406
408
                # calculate copyright overlay pos
407
409
                pos = self.pos.replace( tok_from, tok_to, 1 )
408
410
 
415
417
        def drawing_area_expose_event( self, widget, event ):
416
418
                x, y, width, height = event.area
417
419
                widget.window.draw_drawable( \
418
 
                                widget.get_style().fg_gc[ gtk.STATE_NORMAL ], \
419
 
                                self.pixmap, x, y, x, y, width, height )
 
420
                        widget.get_style().fg_gc[ gtk.STATE_NORMAL ], \
 
421
                        self.pixmap, x, y, x, y, width, height )
420
422
                return False