/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 src/add_copyright_to_images/main_window.py

  • Committer: edam
  • Date: 2011-02-23 19:43:45 UTC
  • Revision ID: edam@waxworlds.org-20110223194345-f7ichg83dzo6m87x
- initial commit, includes project and build setup

Show diffs side-by-side

added added

removed removed

2
2
#
3
3
# Copyright (C) 2011 Tim Marston <edam@waxworlds.org>
4
4
#
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
 
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
7
8
# information.
8
9
#
9
10
# This program is free software: you can redistribute it and/or modify
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
 
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
12
13
# (at your option) any later version.
13
14
#
14
15
# This program is distributed in the hope that it will be useful,
15
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
# GNU General Public License for more details.
 
18
# GNU Lesser General Public License for more details.
18
19
#
19
 
# You should have received a copy of the GNU General Public License
 
20
# You should have received a copy of the GNU Lesser General Public License
20
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22
 
22
23
 
53
54
                # work out the initial size of the drawing area so that the greatest of
54
55
                # the two dimensions is 450px
55
56
                scale = min( \
56
 
                        float( self.DRAWING_AREA_INIT_WIDTH ) / self.pic.get_width(), \
57
 
                        float( self.DRAWING_AREA_INIT_HEIGHT ) / self.pic.get_height() )
 
57
                                float( self.DRAWING_AREA_INIT_WIDTH ) / self.pic.get_width(), \
 
58
                                float( self.DRAWING_AREA_INIT_HEIGHT ) / self.pic.get_height() )
58
59
                init_width = int( round( scale * self.pic.get_width() ) )
59
60
                init_height = int( round( scale * self.pic.get_height() ) )
60
61
 
73
74
                self.drawing_area = gtk.DrawingArea()
74
75
                self.drawing_area.set_size_request( init_width, init_height )
75
76
                self.drawing_area.add_events( gtk.gdk.POINTER_MOTION_MASK | \
76
 
                        gtk.gdk.POINTER_MOTION_HINT_MASK | \
77
 
                        gtk.gdk.BUTTON_PRESS_MASK )
 
77
                                gtk.gdk.POINTER_MOTION_HINT_MASK | \
 
78
                                gtk.gdk.BUTTON_PRESS_MASK )
78
79
                self.drawing_area.connect( "configure_event", \
79
 
                        self.drawing_area_configure_event )
 
80
                                self.drawing_area_configure_event )
80
81
                self.drawing_area.connect( "expose_event", \
81
 
                        self.drawing_area_expose_event )
 
82
                                self.drawing_area_expose_event )
82
83
                self.drawing_area.connect( "motion_notify_event", \
83
 
                        self.motion_notify_event )
 
84
                                self.motion_notify_event )
84
85
                self.drawing_area.connect( "button_press_event", \
85
 
                        self.drawing_area_button_press_event )
 
86
                                self.drawing_area_button_press_event )
86
87
                vbox.pack_start( self.drawing_area, True, True, 0 )
87
88
 
88
89
                # create buttons
100
101
                left_button_box.pack_start( prefs_button, True, True, 0 )
101
102
                cancel_button = gtk.Button( stock = gtk.STOCK_CANCEL )
102
103
                cancel_button.connect_object( "clicked", gtk.Widget.destroy, \
103
 
                        self.window )
 
104
                                self.window )
104
105
                button_box.pack_end( cancel_button, True, True, 0 )
105
106
                self.ok_button = gtk.Button( stock = gtk.STOCK_APPLY )
106
107
                self.ok_button.connect( "clicked", self.ok_button_pressed )
116
117
                self.load_copyright_image()
117
118
 
118
119
        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
 
                # calculate program args
 
213
                # caluclate 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", "src-over", "-composite", \
223
 
                        out_filename ]
 
220
                                os.path.expanduser( self.prefs.copyright_filename ), \
 
221
                                "-geometry", copyright_geometry, \
 
222
                                "-compose", "screen", "-composite", \
 
223
                                out_filename ]
224
224
                if( self.prefs.resize ):
225
225
                        args[ 1 : 1 ] = [ "(", "-resize", resize_geometry, \
226
 
                                self.filename, "-unsharp", "1x3+.6+.09", ")" ]
 
226
                                        self.filename, ")" ]
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 )
233
232
                        ret = call( args )
234
233
                        if ret != 0:
235
234
                                print >>sys.stderr, "ImageMagick failed, returned ", ret
244
243
                                os.rename( self.filename, self.filename + ".old" )
245
244
                        except OSError as e:
246
245
                                print >>sys.stderr, "Could not rename original image file: ", \
247
 
                                        e.strerror
 
246
                                                e.strerror
248
247
                                exit( 1 )
249
248
 
250
249
                        # move new file in-place
312
311
                        state = event.state
313
312
 
314
313
                # calculate copyright overlay pos
315
 
                pos = ( "top" if y <= height / 2 else "bottom" ) + "-" + \
316
 
                        ( "left" if x <= width / 2 else "right" )
 
314
                pos =   ( "top" if y <= height / 2 else "bottom" ) + "-" + \
 
315
                                ( "left" if x <= width / 2 else "right" )
317
316
 
318
317
                # redraw if necessary
319
318
                if getattr( self, "pos", None ) != pos:
332
331
 
333
332
                # work out minimum scale required to fit pic_orig in to the widget area
334
333
                scale = min( float( width ) / self.pic.get_width(),
335
 
                        float( height ) / self.pic.get_height() )
 
334
                                float( height ) / self.pic.get_height() )
336
335
 
337
336
                # scale the images
338
337
                self.pic_scale = self.pic.scale_simple( \
339
 
                        int( round( scale * self.pic.get_width() ) ), \
340
 
                        int( round( scale * self.pic.get_height() ) ), \
341
 
                        gtk.gdk.INTERP_BILINEAR )
 
338
                                int( round( scale * self.pic.get_width() ) ), \
 
339
                                int( round( scale * self.pic.get_height() ) ), \
 
340
                                gtk.gdk.INTERP_BILINEAR )
342
341
                if self.copyright_pic != None:
343
342
                        self.copyright_pic_scale = self.copyright_pic.scale_simple( \
344
 
                                int( round( scale * self.copyright_pic.get_width() ) ), \
345
 
                                int( round( scale * self.copyright_pic.get_height() ) ), \
346
 
                                gtk.gdk.INTERP_BILINEAR )
 
343
                                        int( round( scale * self.copyright_pic.get_width() ) ), \
 
344
                                        int( round( scale * self.copyright_pic.get_height() ) ), \
 
345
                                        gtk.gdk.INTERP_BILINEAR )
347
346
 
348
347
                # recreate the pixmap to render to the screen
349
348
                self.generate_pixmap()
352
351
                widget = self.drawing_area
353
352
                x, y, width, height = widget.get_allocation()
354
353
 
355
 
                # calculate offsets to centre pic in drawing area
 
354
                # calculate offsets to center pic in drawing area
356
355
                pre_width = ( width - self.pic_scale.get_width() ) / 2
357
356
                pre_height = ( height - self.pic_scale.get_height() ) / 2
358
357
                post_width = width - self.pic_scale.get_width() - pre_width
365
364
                pixbuf = self.pic_scale.copy()
366
365
 
367
366
                if self.copyright_pic != None and \
368
 
                        getattr( self, "copyright_pic_scale", None ) != None:
 
367
                                getattr( self, "copyright_pic_scale", None ) != None:
369
368
 
370
369
                        # work out position of copyright overlay
371
370
                        if self.pos == "top-left" or self.pos == "bottom-left":
372
371
                                x = 0
373
372
                        if self.pos == "top-right" or self.pos == "bottom-right":
374
373
                                x = self.pic_scale.get_width() - \
375
 
                                        self.copyright_pic_scale.get_width()
 
374
                                                self.copyright_pic_scale.get_width()
376
375
                        if self.pos == "top-left" or self.pos == "top-right":
377
376
                                y = 0
378
377
                        if self.pos == "bottom-left" or self.pos == "bottom-right":
379
378
                                y = self.pic_scale.get_height() - \
380
 
                                        self.copyright_pic_scale.get_height()
 
379
                                                self.copyright_pic_scale.get_height()
381
380
 
382
381
                        # draw copyright
383
382
                        self.copyright_pic_scale.composite( pixbuf, x, y, \
384
 
                                self.copyright_pic_scale.get_width(), \
385
 
                                self.copyright_pic_scale.get_height(), \
386
 
                                x, y, 1, 1, gtk.gdk.INTERP_NEAREST, 255 )
 
383
                                        self.copyright_pic_scale.get_width(), \
 
384
                                        self.copyright_pic_scale.get_height(), \
 
385
                                        x, y, 1, 1, gtk.gdk.INTERP_NEAREST, 255 )
387
386
 
388
 
                # draw composite pixbuf to the off-screen pixmap
 
387
                # draw composit pixbuf to the off-screen pixmap
389
388
                self.pixmap.draw_pixbuf( widget.get_style().white_gc, \
390
 
                        pixbuf, 0, 0, pre_width, pre_height, \
391
 
                        pixbuf.get_width(), pixbuf.get_height() )
 
389
                                pixbuf, 0, 0, pre_width, pre_height, \
 
390
                                pixbuf.get_width(), pixbuf.get_height() )
392
391
 
393
 
                # draw black rectangles if the pic is being centred
 
392
                # draw black rectangles if the pic is being centered
394
393
                if pre_width > 0 or pre_height > 0:
395
394
                        self.pixmap.draw_rectangle( widget.get_style().black_gc, True, \
396
 
                                0, 0, \
397
 
                                pre_width if pre_width > 0 else width, \
398
 
                                pre_height if pre_height > 0 else height )
 
395
                                        0, 0, \
 
396
                                        pre_width if pre_width > 0 else width, \
 
397
                                        pre_height if pre_height > 0 else height )
399
398
                if post_width > 0 or post_height > 0:
400
399
                        self.pixmap.draw_rectangle( widget.get_style().black_gc, True, \
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 )
 
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 )
405
404
 
406
405
        def move_pos( self, tok_from, tok_to ):
407
 
 
408
406
                # calculate copyright overlay pos
409
407
                pos = self.pos.replace( tok_from, tok_to, 1 )
410
408
 
417
415
        def drawing_area_expose_event( self, widget, event ):
418
416
                x, y, width, height = event.area
419
417
                widget.window.draw_drawable( \
420
 
                        widget.get_style().fg_gc[ gtk.STATE_NORMAL ], \
421
 
                        self.pixmap, x, y, x, y, width, height )
 
418
                                widget.get_style().fg_gc[ gtk.STATE_NORMAL ], \
 
419
                                self.pixmap, x, y, x, y, width, height )
422
420
                return False