File Coverage

blib/lib/Tk/Image/Cut.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #*** Cut.pm ***#
2             # Copyright (C) 2006 by Torsten Knorr
3             # create-soft@tiscali.de
4             # All rights reserved!
5             #-------------------------------------------------
6             package Tk::Image::Cut;
7             #-------------------------------------------------
8 1     1   21456 use strict;
  1         3  
  1         44  
9 1     1   5 use warnings;
  1         2  
  1         32  
10 1     1   367 use Tk;
  0            
  0            
11             use Tk::Frame;
12             use Tk::FileSelect;
13             use Tk::JPEG;
14             use Tk::PNG;
15             use Tk::Image::Calculation;
16             #-------------------------------------------------
17             @Tk::Image::Cut::ISA = qw(Tk::Frame Tk::Image::Calculation);
18             $Tk::Image::Cut::VERSION = '0.07';
19             Construct Tk::Widget "Cut";
20             #-------------------------------------------------
21             sub Populate
22             {
23             require Tk::Button;
24             require Tk::BrowseEntry;
25             require Tk::Entry;
26             require Tk::Label;
27             require Tk::Canvas;
28             my ($cut, $args) = @_;
29             #-------------------------------------------------
30             my @grid = qw(
31             -column 0
32             -row 0
33             -sticky nswe
34             );
35             $cut->{ap_x1} = $cut->{ap_x2} = $cut->{ap_y1} = $cut->{ap_y2} = 1;
36             #-------------------------------------------------
37             # -aperturecolor
38             # -aperturewidth
39             # -shape => rectangle, oval, circle, polygon
40             # -zoom
41             # -shrink
42             #-------------------------------------------------
43             $cut->{_aperturecolor} = (defined($args->{-aperturecolor})) ?
44             delete($args->{-aperturecolor}) : "#00FF00";
45             $cut->{_aperturewidth} = (defined($args->{-aperturewidth})) ?
46             delete($args->{-aperturewidth}) : 4;
47             $cut->{_shape} = (defined($args->{-shape})) ?
48             delete($args->{-shape}) : "rectangle";
49             $cut->{_zoom_out} = (defined($args->{-zoom})) ?
50             delete($args->{-zoom}) : 1;
51             $cut->{_shrink_out} = (defined($args->{-shrink})) ?
52             delete($args->{-shrink}) : 1;
53             $cut->SUPER::Populate($args);
54             #-------------------------------------------------
55             $cut->{button_select_image} = $cut->Button(
56             -text => "Select Image",
57             -command => [\&SelectImage, $cut],
58             )->grid(
59             @grid,
60             );
61             #-------------------------------------------------
62             $grid[1]++;
63             $cut->{label_shape} = $cut->Label(
64             -text => "Shape ->",
65             )->grid(
66             @grid,
67             );
68             #-------------------------------------------------
69             $grid[1]++;
70             $cut->{bentry_shape} = $cut->BrowseEntry(
71             -variable => \$cut->{_shape},
72             -browsecmd => [\&SetShape, $cut]
73             )->grid(
74             @grid,
75             );
76             $cut->{bentry_shape}->insert(qw/
77             end
78             rectangle
79             oval
80             circle
81             polygon
82             /);
83             #-------------------------------------------------
84             $grid[1]++;
85             $cut->{button_color} = $cut->Button(
86             -text => "Select Color",
87             -command => [\&SelectColor, $cut],
88             )->grid(
89             @grid
90             );
91             if($cut->{_shape} eq "rectangle")
92             {
93             $cut->{button_color}->configure(
94             -state => "disabled",
95             );
96             }
97             #-------------------------------------------------
98             $grid[1]++;
99             $cut->{label_width_out} = $cut->Label(
100             -text => "Width ->",
101             )->grid(
102             @grid,
103             );
104             #-------------------------------------------------
105             $grid[1]++;
106             $cut->{entry_width_out} = $cut->Entry(
107             -textvariable => \$cut->{_new_image_width},
108             )->grid(
109             @grid,
110             );
111             #-------------------------------------------------
112             $grid[1]++;
113             $cut->{label_height_out} = $cut->Label(
114             -text => "Height ->",
115             )->grid(
116             @grid,
117             );
118             #------------------------------------------------
119             $grid[1]++;
120             $cut->{entry_height_out} = $cut->Entry(
121             -textvariable => \$cut->{_new_image_height},
122             )->grid(
123             @grid,
124             );
125             #-------------------------------------------------
126             $grid[1]++;
127             $cut->{button_increase} = $cut->Button(
128             -text => '+',
129             -command => [\&ImageIncrease, $cut]
130             )->grid(
131             @grid,
132             );
133             #-------------------------------------------------
134             $grid[1]++;
135             $cut->{button_reduce} = $cut->Button(
136             -text => '-',
137             -command => [\&ImageReduce, $cut],
138             )->grid(
139             @grid,
140             );
141             #-------------------------------------------------
142             $grid[1]++;
143             $cut->{label_name_out} = $cut->Label(
144             -text => "New Image Name ->",
145             )->grid(
146             @grid,
147             );
148             #-------------------------------------------------
149             $grid[1]++;
150             $cut->{entry_name_out} = $cut->Entry(
151             -textvariable => \$cut->{_new_image_name},
152             )->grid(
153             @grid,
154             );
155             #-------------------------------------------------
156             $grid[1]++;
157             $cut->{button_cut} = $cut->Button(
158             -text => "Cut",
159             -command => [\&ImageCut, $cut],
160             )->grid(
161             @grid,
162             );
163             #-------------------------------------------------
164             $grid[1]++;
165             $cut->{canvas} = $cut->Scrolled(
166             "Canvas",
167             )->grid(
168             -column => 0,
169             -row => 1,
170             -columnspan => $grid[1],
171             -sticky => "nswe",
172             );
173             #-------------------------------------------------
174             $cut->{childs} = {
175             "ButtonSelectImage" => $cut->{button_select_image},
176             "LabelShape" => $cut->{label_shape},
177             "bEntryShape" => $cut->{bentry_shape},
178             "ButtonColor" => $cut->{button_color},
179             "LabelWidthOut" => $cut->{label_width_out},
180             "EntryWidthOut" => $cut->{entry_width_out},
181             "LabelHeightOut" => $cut->{label_height_out},
182             "EntryHeightOut" => $cut->{entry_height_out},
183             "ButtonIncrease" => $cut->{button_increase},
184             "ButtonReduce" => $cut->{button_reduce},
185             "LabelNameOut" => $cut->{label_name_out},
186             "EntryNameOut" => $cut->{entry_name_out},
187             "ButtonCut" => $cut->{button_cut},
188             "Canvas" => $cut->{canvas},
189             };
190             $cut->Advertise($_, $cut->{childs}{$_}) for(keys(%{$cut->{childs}}));
191             $cut->Delegates(DEFAULT => $cut->{canvas});
192             $cut->ConfigSpecs(DEFAULT => ["ADVERTISED"]);
193             }
194             #-------------------------------------------------
195             sub SelectImage
196             {
197             my ($self) = @_;
198             $self->{_zoom_out} = 1;
199             $self->{_shrink_out} = 1;
200             if($self->{file_in} = $self->FileSelect()->Show())
201             {
202             $self->{canvas}->delete("all");
203             # GIF, XBM, XPM, BMP, JPEG, PNG, PPM, PGM
204             if($self->{file_in} =~ m/.+?\.(?:jpg|jpeg)$/i)
205             {
206             $self->{image_format} = "JPEG";
207             }
208             elsif($self->{file_in} =~ m/.+?\.([a-zA-Z]{3})$/)
209             {
210             $self->{image_format} = uc($1);
211             }
212             else
213             {
214             print("error in extracting image format at Tk::Image::Cut::SelectImage()\n");
215             $self->{canvas}->createText(10, 10,
216             -text => "error in extracting image format",
217             -anchor => "nw",
218             );
219             return;
220             }
221             $self->{image_in} = $self->Photo(
222             -file => $self->{file_in},
223             -format => $self->{image_format},
224             );
225             $self->{image_in_width} = $self->{image_in}->width();
226             $self->{image_in_height} = $self->{image_in}->height();
227             $self->{canvas}->configure(
228             -scrollregion => [0, 0, $self->{image_in_width}, $self->{image_in_height}],
229             );
230             $self->{canvas}->createImage(0, 0,
231             -image => $self->{image_in},
232             -anchor => "nw",
233             -tags => "image"
234             );
235             if(($self->{canvas}->width() < $self->{image_in_width}) or
236             ($self->{canvas}->height() < $self->{image_in_height}))
237             {
238             $self->{canvas}->bind("image", "", [\&Scroll, $self, Ev('x'), Ev('y')]);
239             }
240             else
241             {
242             $self->{canvas}->bind("image", "", sub { });
243             }
244             $self->CreateAperture();
245             }
246             return 1;
247             }
248             #-------------------------------------------------
249             sub ImageIncrease
250             {
251             my ($self) = @_;
252             if($self->{_shrink_out} > 1) { $self->{_shrink_out}--; }
253             else { $self->{_zoom_out}++; }
254             $self->SetImageOutWidth();
255             $self->SetImageOutHeight();
256             $self->SetImageOutName();
257             return 1;
258             }
259             #-------------------------------------------------
260             sub ImageReduce
261             {
262             my ($self) = @_;
263             if($self->{_zoom_out} > 1) { $self->{_zoom_out}--; }
264             else { $self->{_shrink_out}++; }
265             $self->SetImageOutWidth();
266             $self->SetImageOutHeight();
267             $self->SetImageOutName();
268             return 1;
269             }
270             #-------------------------------------------------
271             sub ImageCut
272             {
273             my ($self) = @_;
274             my $temp_image = $self->Photo(
275             -file => $self->{file_in},
276             -format => $self->{image_format}
277             );
278             my $ref_p_out;
279             if($self->{_shape} eq "rectangle")
280             {
281             $ref_p_out = [];
282             }
283             elsif($self->{_shape} eq "oval")
284             {
285             $ref_p_out = $self->GetPointsOutOval(
286             $self->{ap_x1},
287             $self->{ap_y1},
288             $self->{ap_x2},
289             $self->{ap_y2}
290             );
291             }
292             elsif($self->{_shape} eq "circle")
293             {
294             $ref_p_out = $self->GetPointsOutCircle(
295             $self->{ap_x1},
296             $self->{ap_y1},
297             $self->{ap_x2},
298             $self->{ap_y2}
299             );
300             }
301             elsif($self->{_shape} eq "polygon")
302             {
303             $ref_p_out = $self->GetPointsOutPolygon(@{$self->{_points_polygon}});
304             }
305             else
306             {
307             warn("unknown picture shape\n");
308             return;
309             }
310             if(defined($self->{_color}))
311             {
312             $temp_image->put($self->{_color}, -to => $_->[0], $_->[1]) for(@{$ref_p_out});
313             }
314             else
315             {
316             $temp_image->transparencySet($_->[0], $_->[1], 1) for(@{$ref_p_out});
317             }
318             $self->{image_out} = $self->Photo(
319             -format => $self->{image_format},
320             -width => $self->{_new_image_width},
321             -height => $self->{_new_image_height}
322             );
323             $self->{image_out}->copy($temp_image,
324             -zoom => $self->{_zoom_out},
325             -subsample => $self->{_shrink_out},
326             -from => $self->{ap_x1}, $self->{ap_y1}, $self->{ap_x2}, $self->{ap_y2},
327             -to => 0, 0, $self->{_new_image_width}, $self->{_new_image_height},
328             );
329             $self->{image_out}->write(
330             $self->{_new_image_name},
331             -format => $self->{image_format},
332             );
333             return 1;
334             }
335             #-------------------------------------------------
336             sub CreateAperture
337             {
338             my ($self) = @_;
339             return if(!(defined($self->{image_in})));
340             $self->DeleteBindings();
341             SWITCH:
342             {
343             #-------------------------------------------------
344             ($self->{_shape}eq "rectangle") && do
345             {
346             $self->{ap_x1} = int($self->{image_in_width} / 5);
347             $self->{ap_y1} = int($self->{image_in_height} / 5);
348             $self->{ap_x2} = int($self->{image_in_width} * 0.8);
349             $self->{ap_y2} = int($self->{image_in_height} * 0.8);
350             $self->{canvas}->delete("aperture");
351             $self->{canvas}->delete("points_out");
352             $self->{aperture} = $self->{canvas}->createRectangle(
353             $self->{ap_x1},
354             $self->{ap_y1},
355             $self->{ap_x2},
356             $self->{ap_y2},
357             -outline => $self->{_aperturecolor},
358             -width => $self->{_aperturewidth},
359             -tags => "aperture",
360             );
361             $self->SetImageOutWidth();
362             $self->SetImageOutHeight();
363             $self->SetImageOutName();
364             $self->{canvas}->bind("aperture", "", [\&ShowCursor, $self, Ev('x'), Ev('y')]);
365             $self->{canvas}->bind(
366             "aperture",
367             "",
368             sub {
369             $self->{canvas}->itemconfigure(
370             "aperture",
371             -outline => "#FF0000",
372             );
373             }
374             );
375             $self->{canvas}->bind(
376             "aperture",
377             "",
378             sub { $self->{canvas}->itemconfigure(
379             "aperture",
380             -outline => $self->{_aperturecolor},
381             );
382             $self->{canvas}->configure(
383             -cursor => "arrow",
384             );
385             });
386             $self->{canvas}->bind("aperture", "", [\&StartMove, $self, Ev('x'), Ev('y')]);
387             $self->{canvas}->bind("aperture", "", [\&EndMove, $self]);
388             last(SWITCH);
389             };
390             #-------------------------------------------------
391             ($self->{_shape} eq "oval") && do
392             {
393             for(qw/image aperture points_out/)
394             {
395             $self->{canvas}->bind($_, "", [\&DrawOval, $self, Ev('x'), Ev('y')]);
396             }
397             last(SWITCH);
398             };
399             #-------------------------------------------------
400             ($self->{_shape} eq "circle") && do
401             {
402             for(qw/image aperture points_out/)
403             {
404             $self->{canvas}->bind($_, "", [\&DrawCircle, $self, Ev('x'), Ev('y')]);
405             }
406             last(SWITCH);
407             };
408             #-------------------------------------------------
409             ($self->{_shape} eq "polygon") && do
410             {
411             for(qw/image aperture points_out/)
412             {
413             $self->{canvas}->bind($_, "", [\&DrawPolygon, $self, Ev('x'), Ev('y')]);
414             }
415             last(SWITCH);
416             };
417             #-------------------------------------------------
418             warn("unknown picture shape\n");
419             }
420             return 1;
421             }
422             #-------------------------------------------------
423             sub DeleteBindings
424             {
425             my ($self) = @_;
426             for my $tag (qw/
427             image
428             aperture
429             templine
430             points_out/)
431             {
432             for my $event (qw/
433            
434            
435            
436            
437             /)
438             {
439             $self->{canvas}->bind($tag, $event, sub { });
440             }
441             }
442             for(qw/ /)
443             {
444             $self->{canvas}->bind("aperture", $_, sub { });
445             }
446             return 1;
447             }
448             #-------------------------------------------------
449             sub StartDraw
450             {
451             my ($canvas, $self, $x, $y) = @_;
452             $self->{ap_x1} = $canvas->canvasx($x);
453             $self->{ap_y1} = $canvas->canvasy($y);
454             $self->{canvas}->delete("aperture");
455             $self->{canvas}->delete("points_out");
456             $canvas->createOval(
457             $self->{ap_x1}, $self->{ap_y1}, $self->{ap_x1}, $self->{ap_y1},
458             -outline => $self->{_aperturecolor},
459             -width => $self->{_aperturewidth},
460             -tags => "aperture"
461             );
462             return 1;
463             }
464             #-------------------------------------------------
465             sub DrawPolygon
466             {
467             my ($canvas, $self, $x, $y) = @_;
468             $x = $canvas->canvasx($x);
469             $y = $canvas->canvasy($y);
470             $self->{canvas}->delete("aperture");
471             $self->{canvas}->delete("points_out");
472             $self->{_point_start_templine} = $self->{_points_polygon} = [$x, $y];
473             $self->{ap_x1} = $self->{ap_x2} = $x;
474             $self->{ap_y1} = $self->{ap_y2} = $y;
475             $canvas->createLine(
476             $x, $y, $x, $y,
477             -tags => "templine",
478             -fill => "#FF0000",
479             -width => $self->{_aperturewidth},
480             );
481             $canvas->createPolygon(
482             0, 0, 0, 0, 0, 0,
483             -outline => $self->{_aperturecolor},
484             -width => $self->{_aperturewidth},
485             -fill => "#FFFFFF",
486             -stipple => "gray25",
487             -tags => "aperture",
488             );
489             for(qw/image templine aperture/)
490             {
491             $canvas->bind($_, "", [\&MovePolygon, $self, Ev('x'), Ev('y')]);
492             $canvas->bind($_, "", [\&EndDrawPolygon, $self, Ev('x'), Ev('y')]);
493             $canvas->bind($_, "", [\&MoveTempLine, $self, Ev('x'), Ev('y')]);
494             }
495             return 1;
496             }
497             #-------------------------------------------------
498             sub MovePolygon
499             {
500             my ($canvas, $self, $x, $y) = @_;
501             $x = $canvas->canvasx($x);
502             $y = $canvas->canvasy($y);
503             push(@{$self->{_points_polygon}}, ($x, $y));
504             if($#{$self->{_points_polygon}} >= 5)
505             {
506             $canvas->coords("aperture", @{$self->{_points_polygon}});
507             }
508             else
509             {
510             $canvas->createLine(
511             @{$self->{_point_start_templine}}, $x, $y,
512             -fill => $self->{_aperturecolor},
513             -width => $self->{_aperturewidth},
514             -tags => "start_line",
515             );
516             }
517             $self->{_point_start_templine} = [$x, $y];
518             $canvas->coords(
519             "templine",
520             $x, $y, $x, $y
521             );
522             return 1;
523             }
524             #-------------------------------------------------
525             sub EndDrawPolygon
526             {
527             my ($canvas, $self, $x, $y) = @_;
528             MovePolygon(@_);
529             for(my $i = 0; $i < $#{$self->{_points_polygon}}; $i += 2)
530             {
531             $self->{ap_x1} = $self->{_points_polygon}[$i] if($self->{_points_polygon}[$i] < $self->{ap_x1});
532             $self->{ap_y1} = $self->{_points_polygon}[$i + 1] if($self->{_points_polygon}[$i + 1] < $self->{ap_y1});
533             $self->{ap_x2} = $self->{_points_polygon}[$i] if($self->{_points_polygon}[$i] > $self->{ap_x2});
534             $self->{ap_y2} = $self->{_points_polygon}[$i + 1] if($self->{_points_polygon}[$i + 1] > $self->{ap_y2});
535             }
536             $self->SetImageOutWidth();
537             $self->SetImageOutHeight();
538             $self->SetImageOutName();
539             my $ref_l_out = $self->GetLinesOutPolygon(@{$self->{_points_polygon}});
540             for(@{$ref_l_out})
541             {
542             $canvas->createLine(
543             $_->[0], $_->[1], $_->[2], $_->[3],
544             -width => 1,
545             -fill => $self->{_color} || "#FFFFFF",
546             -tags => "points_out"
547             );
548             }
549             $canvas->delete("start_line");
550             $self->CreateAperture();
551             return 1;
552             }
553             #-------------------------------------------------
554             sub MoveTempLine
555             {
556             my ($canvas, $self, $x, $y) = @_;
557             $canvas->coords(
558             "templine",
559             @{$self->{_point_start_templine}},
560             $canvas->canvasx($x),
561             $canvas->canvasy($y)
562             );
563             return 1;
564             }
565             #-------------------------------------------------
566             sub DrawCircle
567             {
568             my ($canvas, $self, $x, $y) = @_;
569             StartDraw(@_);
570             for(qw/image aperture/)
571             {
572             $canvas->bind($_, "", [\&MoveCircle, $self, Ev('x'), Ev('y')]);
573             $canvas->bind($_, "", [\&EndDrawCircle, $self, Ev('x'), Ev('y')]);
574             }
575             return 1;
576             }
577             #-------------------------------------------------
578             sub MoveCircle
579             {
580             my ($canvas, $self, $x, $y) = @_;
581             $x = $canvas->canvasx($x);
582             $y = $canvas->canvasy($y);
583             my $diff_x = ($x - $self->{ap_x1});
584             my $diff_y = ($y - $self->{ap_y1});
585             my $diff_max = (abs($diff_x) < abs($diff_y)) ? abs($diff_y) : abs($diff_x);
586             if($diff_x < 0)
587             {
588             $self->{ap_x2} = ($self->{ap_x1} - $diff_max);
589             }
590             else
591             {
592             $self->{ap_x2} = ($self->{ap_x1} + $diff_max);
593             }
594             if($diff_y < 0)
595             {
596             $self->{ap_y2} = ($self->{ap_y1} - $diff_max);
597             }
598             else
599             {
600             $self->{ap_y2} = ($self->{ap_y1} + $diff_max);
601             }
602             $canvas->coords(
603             "aperture",
604             $self->{ap_x1},
605             $self->{ap_y1},
606             $self->{ap_x2},
607             $self->{ap_y2},
608             );
609             $self->SetImageOutHeight();
610             $self->SetImageOutWidth();
611             return 1;
612             }
613             #-------------------------------------------------
614             sub EndDrawCircle
615             {
616             my ($canvas, $self, $x, $y) = @_;
617             MoveCircle(@_);
618             $self->SetImageOutName();
619             my ($ref_l_out) = $self->GetLinesOutCircle(
620             $self->{ap_x1},
621             $self->{ap_y1},
622             $self->{ap_x2},
623             $self->{ap_y2}
624             );
625             for(@{$ref_l_out})
626             {
627             $canvas->createLine(
628             $_->[0], $_->[1], $_->[2], $_->[3],
629             -width => 1,
630             -fill => $self->{_color} || "#FFFFFF",
631             -tags => "points_out"
632             );
633             }
634             $self->CreateAperture();
635             return 1;
636             }
637             #-------------------------------------------------
638             sub DrawOval
639             {
640             my ($canvas, $self, $x, $y) = @_;
641             StartDraw(@_);
642             for(qw/image aperture/)
643             {
644             $canvas->bind($_, "", [\&MoveOval, $self, Ev('x'), Ev('y')]);
645             $canvas->bind($_, "", [\&EndDrawOval, $self, Ev('x'), Ev('y')]);
646             }
647             return 1;
648             }
649             #-------------------------------------------------
650             sub MoveOval
651             {
652             my ($canvas, $self, $x, $y) = @_;
653             $self->{ap_x2} = $canvas->canvasx($x);
654             $self->{ap_y2} = $canvas->canvasy($y);
655             $canvas->coords(
656             "aperture",
657             $self->{ap_x1},
658             $self->{ap_y1},
659             $self->{ap_x2},
660             $self->{ap_y2}
661             );
662             $self->SetImageOutHeight();
663             $self->SetImageOutWidth();
664             return 1;
665             }
666             #-------------------------------------------------
667             sub EndDrawOval
668             {
669             my ($canvas, $self, $x, $y) = @_;
670             MoveOval(@_);
671             $self->SetImageOutName();
672             my ($ref_l_out) = $self->GetLinesOutOval(
673             $self->{ap_x1},
674             $self->{ap_y1},
675             $self->{ap_x2},
676             $self->{ap_y2}
677             );
678             for(@{$ref_l_out})
679             {
680             $canvas->createLine(
681             $_->[0], $_->[1], $_->[2], $_->[3],
682             -width => 1,
683             -fill => $self->{_color} || "#FFFFFF",
684             -tags => "points_out"
685             );
686             }
687             $self->CreateAperture();
688             return 1;
689             }
690             #-------------------------------------------------
691             sub Scroll
692             {
693             my ($canvas, $self, $x, $y) = @_;
694             $x = $canvas->canvasx($x);
695             $y = $canvas->canvasy($y);
696             my ($part_x1, $part_x2) = $canvas->xview();
697             my ($part_y1, $part_y2) = $canvas->yview();
698             my $pos_x1 = ($self->{image_in_width} * $part_x1);
699             my $pos_x2 = ($self->{image_in_width} * $part_x2);
700             my $pos_y1 = ($self->{image_in_height} * $part_y1);
701             my $pos_y2 = ($self->{image_in_height} * $part_y2);
702             SWITCH:
703             {
704             (($x > $pos_x2) && ($y < $pos_y2)) && do
705             {
706             $canvas->xviewScroll(1, "units");
707             last(SWITCH);
708             };
709             (($x < $pos_x1) && ($y < $pos_y2)) && do
710             {
711             $canvas->xviewScroll(-1, "units");
712             last(SWITCH);
713             };
714             (($y > $pos_y2) && ($x < $pos_x2)) && do
715             {
716             $canvas->yviewScroll(1, "units");
717             last(SWITCH);
718             };
719             (($y < $pos_y1) && ($x < $pos_x2)) && do
720             {
721             $canvas->yviewScroll(-1, "units");
722             last(SWITCH);
723             };
724             }
725             return 1;
726             }
727             #-------------------------------------------------
728             sub ShowCursor
729             {
730             my ($canvas, $self, $x, $y) = @_;
731             $x = $canvas->canvasx($x);
732             $y = $canvas->canvasy($y);
733             SWITCH:
734             {
735             (($x > ($self->{ap_x1} + 10)) &&
736             ($x < ($self->{ap_x2} - 10)) &&
737             ($y > ($self->{ap_y1} - 4)) &&
738             ($y < ($self->{ap_y1} + 4))) && do
739             {
740             $self->{cursor_style} = "top_side";
741             last SWITCH;
742             };
743             (($x > ($self->{ap_x1} + 10)) &&
744             ($x < ($self->{ap_x2} - 10)) &&
745             ($y > ($self->{ap_y2} - 4)) &&
746             ($y < ($self->{ap_y2} + 4))) && do
747             {
748             $self->{cursor_style} = "bottom_side",
749             last SWITCH;
750             };
751             (($y > ($self->{ap_y1} + 10)) &&
752             ($y < ($self->{ap_y2} - 10)) &&
753             ($x > ($self->{ap_x1} - 4)) &&
754             ($x < ($self->{ap_x1} +4))) && do
755             {
756             $self->{cursor_style} = "left_side";
757             last SWITCH;
758             };
759             (($y > ($self->{ap_y1} + 10)) &&
760             ($y < ($self->{ap_y2} - 10)) &&
761             ($x > ($self->{ap_x2} - 4)) &&
762             ($x < ($self->{ap_x2} + 4))) && do
763             {
764             $self->{cursor_style} = "right_side";
765             last SWITCH;
766             };
767             ((($x >= $self->{ap_x1}) &&
768             ($x <= ($self->{ap_x1} + 10)) &&
769             ($y >= ($self->{ap_y1} - 4)) &&
770             ($y <= ($self->{ap_y1} + 4))) ||
771             (($y >= $self->{ap_y1}) &&
772             ($y <= ($self->{ap_y1} + 10)) &&
773             ($x >= ($self->{ap_x1} - 4)) &&
774             ($x <= ($self->{ap_x1} + 4)))) && do
775             {
776             $self->{cursor_style} = "top_left_corner";
777             last SWITCH;
778             };
779             ((($x <= $self->{ap_x2}) &&
780             ($x >= ($self->{ap_x2} - 10)) &&
781             ($y <= ($self->{ap_y1} + 4)) &&
782             ($y >= ($self->{ap_y1} - 4))) ||
783             (($y >= $self->{ap_y1}) &&
784             ($y <= ($self->{ap_y1} + 10)) &&
785             ($x <= ($self->{ap_x2} + 4)) &&
786             ($x >= ($self->{ap_x2} - 4)))) && do
787             {
788             $self->{cursor_style} = "top_right_corner";
789             last SWITCH;
790             };
791             ((($y >= ($self->{ap_y2} - 10)) &&
792             ($y <= $self->{ap_y2}) &&
793             ($x <= ($self->{ap_x1} + 4)) &&
794             ($x >= ($self->{ap_x1} - 4))) ||
795             (($x >= $self->{ap_x1}) &&
796             ($x <= ($self->{ap_x1} + 10)) &&
797             ($y <= ($self->{ap_y2} + 4)) &&
798             ($y >= ($self->{ap_y2} - 4)))) && do
799             {
800             $self->{cursor_style} = "bottom_left_corner";
801             last SWITCH;
802             };
803             ((($x <= $self->{ap_x2}) &&
804             ($x >= ($self->{ap_x2} - 10)) &&
805             ($y <= ($self->{ap_y2} + 4)) &&
806             ($y >= ($self->{ap_y2} - 4))) ||
807             (($y <= $self->{ap_y2}) &&
808             ($y >= ($self->{ap_y2} - 10)) &&
809             ($x <= ($self->{ap_x2} + 4)) &&
810             ($x >= ($self->{ap_x2} - 4)))) && do
811             {
812             $self->{cursor_style} = "bottom_right_corner";
813             last SWITCH;
814             };
815             $self->{cursor_style} = "arrow";
816             }
817             $self->{canvas}->configure(
818             -cursor => $self->{cursor_style},
819             );
820             return 1;
821             }
822             #-------------------------------------------------
823             sub StartMove
824             {
825             my ($canvas, $self, $x, $y) = @_;
826             $x = $canvas->canvasx($x);
827             $y = $canvas->canvasy($y);
828             SWITCH:
829             {
830             ($self->{cursor_style} eq "top_side") && do
831             {
832             $canvas->bind("aperture", "", [\&MoveUpperLine, $self, Ev('y')]);
833             last SWITCH;
834             };
835             ($self->{cursor_style} eq "bottom_side") && do
836             {
837             $canvas->bind("aperture", "", [\&MoveUnderLine, $self, Ev('y')]);
838             last SWITCH;
839             };
840             ($self->{cursor_style} eq "left_side") && do
841             {
842             $canvas->bind("aperture", "", [\&MoveLeftLine, $self, Ev('x')]);
843             last SWITCH;
844             };
845             ($self->{cursor_style} eq "right_side") && do
846             {
847             $canvas->bind("aperture", "", [\&MoveRightLine, $self, Ev('x')]);
848             last SWITCH;
849             };
850             ($self->{cursor_style} eq "top_left_corner") && do
851             {
852             $canvas->bind("aperture", "", [\&MoveUpperLeftCorner, $self, Ev('x'), Ev('y')]);
853             last SWITCH;
854             };
855             ($self->{cursor_style} eq "top_right_corner") && do
856             {
857             $canvas->bind("aperture", "", [\&MoveUpperRightCorner, $self, Ev('x'), Ev('y')]);
858             last SWITCH;
859             };
860             ($self->{cursor_style} eq "bottom_left_corner") && do
861             {
862             $canvas->bind("aperture", "", [\&MoveUnderLeftCorner, $self, Ev('x'), Ev('y')]);
863             last SWITCH;
864             };
865             ($self->{cursor_style} eq "bottom_right_corner") && do
866             {
867             $canvas->bind("aperture", "", [\&MoveUnderRightCorner, $self, Ev('x'), Ev('y')]);
868             last SWITCH;
869             };
870             $canvas->bind("aperture", "", sub { });
871             }
872             return 1;
873             }
874             #-------------------------------------------------
875             sub EndMove
876             {
877             my ($canvas, $self) = @_;
878             $canvas->bind("aperture", "", [\&ShowCursor, $self, Ev('x'), Ev('y')]);
879             $self->SetImageOutName();
880             return 1;
881             }
882             #-------------------------------------------------
883             sub MoveUpperLine
884             {
885             my ($canvas, $self, $y) = @_;
886             $self->{ap_y1} = $canvas->canvasy($y);
887             $self->SetImageOutHeight();
888             $self->Move();
889             return 1;
890             }
891             #-------------------------------------------------
892             sub MoveUnderLine
893             {
894             my ($canvas, $self, $y) = @_;
895             $self->{ap_y2} = $canvas->canvasy($y);
896             $self->SetImageOutHeight();
897             $self->Move();
898             return 1;
899             }
900             #-------------------------------------------------
901             sub MoveLeftLine
902             {
903             my($canvas, $self, $x) = @_;
904             $self->{ap_x1} = $canvas->canvasx($x);
905             $self->SetImageOutWidth();
906             $self->Move();
907             return 1;
908             }
909             #-------------------------------------------------
910             sub MoveRightLine
911             {
912             my ($canvas, $self, $x) = @_;
913             $self->{ap_x2} = $canvas->canvasx($x);
914             $self->SetImageOutWidth();
915             $self->Move();
916             return 1;
917             }
918             #-------------------------------------------------
919             sub MoveUpperLeftCorner
920             {
921             my ($canvas, $self, $x, $y) = @_;
922             $self->{ap_x1} = $canvas->canvasx($x);
923             $self->{ap_y1} = $canvas->canvasy($y);
924             $self->SetImageOutWidth();
925             $self->SetImageOutHeight();
926             $self->Move();
927             return 1;
928             }
929             #-------------------------------------------------
930             sub MoveUpperRightCorner
931             {
932             my ($canvas, $self, $x, $y) = @_;
933             $self->{ap_x2} = $canvas->canvasx($x);
934             $self->{ap_y1} = $canvas->canvasy($y);
935             $self->SetImageOutWidth();
936             $self->SetImageOutHeight();
937             $self->Move();
938             return 1;
939             }
940             #--------------------------------------------------
941             sub MoveUnderLeftCorner
942             {
943             my ($canvas, $self, $x, $y) = @_;
944             $self->{ap_x1} = $canvas->canvasx($x);
945             $self->{ap_y2} = $canvas->canvasy($y);
946             $self->SetImageOutWidth();
947             $self->SetImageOutHeight();
948             $self->Move();
949             return 1;
950             }
951             #-------------------------------------------------
952             sub MoveUnderRightCorner
953             {
954             my ($canvas, $self, $x, $y) = @_;
955             $self->{ap_x2} = $canvas->canvasx($x);
956             $self->{ap_y2} = $canvas->canvasy($y);
957             $self->SetImageOutWidth();
958             $self->SetImageOutHeight();
959             $self->Move();
960             return 1;
961             }
962             #-------------------------------------------------
963             sub Move
964             {
965             my ($self) = @_;
966             $self->{canvas}->coords(
967             "aperture",
968             $self->{ap_x1},
969             $self->{ap_y1},
970             $self->{ap_x2},
971             $self->{ap_y2},
972             );
973             return 1;
974             }
975             #-------------------------------------------------
976             sub SetImageOutWidth
977             {
978             my ($self) = @_;
979             ($self->{ap_x1}, $self->{ap_x2}) = ($self->{ap_x2}, $self->{ap_x1}) if($self->{ap_x1} > $self->{ap_x2});
980             ($self->{ap_y1}, $self->{ap_y2}) = ($self->{ap_y2}, $self->{ap_y1}) if($self->{ap_y1} > $self->{ap_y2});
981             $self->{_new_image_width} =
982             int(
983             ($self->{ap_x2} - $self->{ap_x1} + 1) *
984             ($self->{_zoom_out} / $self->{_shrink_out})
985             );
986             return 1;
987             }
988             #-------------------------------------------------
989             sub SetImageOutHeight
990             {
991             my ($self) = @_;
992             ($self->{ap_x1}, $self->{ap_x2}) = ($self->{ap_x2}, $self->{ap_x1}) if($self->{ap_x1} > $self->{ap_x2});
993             ($self->{ap_y1}, $self->{ap_y2}) = ($self->{ap_y2}, $self->{ap_y1}) if($self->{ap_y1} > $self->{ap_y2});
994             $self->{_new_image_height} =
995             int(
996             ($self->{ap_y2} - $self->{ap_y1} + 1) *
997             ($self->{_zoom_out} / $self->{_shrink_out})
998             );
999             return 1;
1000             }
1001             #-------------------------------------------------
1002             sub SetImageOutName
1003             {
1004             my ($self) = @_;
1005             $self->{file_in} =~ m/(.+?)(\.\w{3,4})$/;
1006             $self->{_new_image_name} = $1 . '_' . $self->{_new_image_width} . 'X' . $self->{_new_image_height} . $2;
1007             return 1;
1008             }
1009             #-------------------------------------------------
1010             sub SetShape
1011             {
1012             my ($self) = @_;
1013             SWITCH:
1014             {
1015             ($self->{_shape} eq "rectangle") && do
1016             {
1017             $self->{button_color}->configure(
1018             -state => "disabled"
1019             );
1020             $self->CreateAperture();
1021             last(SWITCH);
1022             };
1023             (($self->{_shape} eq "oval") or
1024             ($self->{_shape} eq "circle") or
1025             ($self->{_shape} eq "polygon")) && do
1026             {
1027             $self->{canvas}->delete("aperture");
1028             $self->{canvas}->delete("points_out");
1029             $self->{button_color}->configure(
1030             -state => "normal"
1031             );
1032             $self->CreateAperture();
1033             last(SWITCH);
1034             };
1035             }
1036             return 1;
1037             }
1038             #-------------------------------------------------
1039             sub SelectColor
1040             {
1041             my ($self) = @_;
1042             $self->{_color} = undef;
1043             $self->{_color} = $self->chooseColor();
1044             $self->{canvas}->itemconfigure(
1045             "points_out",
1046             -fill => $self->{_color} || "#FFFFFF"
1047             );
1048             return 1;
1049             }
1050             #-------------------------------------------------
1051             1;
1052             #-------------------------------------------------
1053             __END__