1111package org .eclipse .swt .snippets ;
1212
1313import org .eclipse .swt .*;
14+ import org .eclipse .swt .events .*;
1415import org .eclipse .swt .graphics .*;
1516import org .eclipse .swt .layout .*;
1617import org .eclipse .swt .widgets .*;
2021 *
2122 * The GC provides two relevant drawImage methods: one that scales an entire
2223 * image to a destination rectangle, and another that crops a source region and
23- * scales it to the destination.
24+ * scales it to the destination. The snippet allows to select any source area
25+ * of an image and draw it to a specific target size. Additionally you can scale
26+ * it additionally to the selected target size and rotate the image.
2427 *
2528 * This snippet allows experimenting with different source and destination
2629 * values for the second method. Within the method, the GC receives the
@@ -39,11 +42,8 @@ public class Snippet389 {
3942 private static final String IMAGE_PATH_100 = IMAGES_ROOT + IMAGE_100 ;
4043 private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200 ;
4144
42- static int srcX , srcY , srcW , srcH ;
43- static int dstX , dstY , dstW , dstH ;
44-
4545 public static void main (String [] args ) {
46-
46+ Display display = new Display ();
4747 ImageFileNameProvider filenameProvider = zoom -> {
4848 switch (zoom ) {
4949 case 100 :
@@ -54,113 +54,12 @@ public static void main(String[] args) {
5454 return null ;
5555 }
5656 };
57-
58- Display display = new Display ();
59- Shell shell = new Shell (display );
60- shell .setText ("GC#drawImage Interactive" );
61- shell .setLayout (new GridLayout (2 , false ));
62-
6357 Image image = new Image (display , filenameProvider );
64- Rectangle imgBounds = image .getBounds ();
65-
66- final int fixedDstW = imgBounds .width * 2 ;
67- final int fixedDstH = imgBounds .height * 2 ;
68- srcX = imgBounds .width / 2 ;
69- srcY = imgBounds .height / 2 ;
70- srcW = imgBounds .width / 2 ;
71- srcH = imgBounds .height / 2 ;
72-
73- dstX = 0 ;
74- dstY = 0 ;
75- dstW = imgBounds .width ;
76- dstH = imgBounds .height ;
77-
78- Group controls = new Group (shell , SWT .NONE );
79- controls .setText ("GC#drawImage Arguments" );
80- controls .setLayoutData (new GridData (SWT .FILL , SWT .FILL , false , true ));
81- controls .setLayout (new GridLayout (2 , false ));
82-
83- Text tSrcX = field (controls , "srcX" , srcX );
84- Text tSrcY = field (controls , "srcY" , srcY );
85- Text tSrcW = field (controls , "srcWidth" , srcW );
86- Text tSrcH = field (controls , "srcHeight" , srcH );
87-
88- Text tDstX = field (controls , "destX" , dstX );
89- Text tDstY = field (controls , "destY" , dstY );
90- Text tDstW = field (controls , "destWidth" , dstW );
91- Text tDstH = field (controls , "destHeight" , dstH );
92-
93- Button apply = new Button (controls , SWT .PUSH );
94- apply .setText ("Apply" );
95- apply .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false , 2 , 1 ));
96-
97- Composite draw = new Composite (shell , SWT .NONE );
98- draw .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
99- draw .setLayout (new GridLayout (2 , true ));
100-
101- Canvas srcCanvas = new Canvas (draw , SWT .BORDER );
102- srcCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
103- srcCanvas .addListener (SWT .Paint , e -> {
104- GC gc = e .gc ;
105- Rectangle ca = srcCanvas .getClientArea ();
106-
107- int ix = (ca .width - imgBounds .width ) / 2 ;
108- int iy = (ca .height - imgBounds .height ) / 2 ;
109-
110- gc .drawImage (image , ix , iy );
111-
112- gc .setLineStyle (SWT .LINE_DASH );
113- gc .setForeground (display .getSystemColor (SWT .COLOR_BLACK ));
114- gc .drawRectangle (ix , iy , imgBounds .width , imgBounds .height );
115-
116- gc .setForeground (display .getSystemColor (SWT .COLOR_RED ));
117- gc .setLineWidth (2 );
118- gc .drawRectangle (ix + srcX , iy + srcY , srcW , srcH );
119- });
120-
121- Canvas dstCanvas = new Canvas (draw , SWT .BORDER );
122- dstCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
123- dstCanvas .addListener (SWT .Paint , e -> {
124- GC gc = e .gc ;
125- Rectangle ca = dstCanvas .getClientArea ();
126-
127- int px = (ca .width - fixedDstW ) / 2 ;
128- int py = (ca .height - fixedDstH ) / 2 ;
129-
130- gc .drawImage (image , srcX , srcY , srcW , srcH , px + dstX , py + dstY , dstW , dstH );
131-
132- gc .setLineStyle (SWT .LINE_DASH );
133- gc .setForeground (display .getSystemColor (SWT .COLOR_BLACK ));
134- gc .drawRectangle (px , py , fixedDstW , fixedDstH );
135-
136- gc .setForeground (display .getSystemColor (SWT .COLOR_RED ));
137- gc .setLineWidth (2 );
138- gc .drawRectangle (px + dstX , py + dstY , dstW , dstH );
139- });
140-
141- Label srcLabel = new Label (draw , SWT .CENTER );
142- srcLabel .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
143- srcLabel .setText ("150 x 150" );
144-
145- Label dstLabel = new Label (draw , SWT .CENTER );
146- dstLabel .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
147- dstLabel .setText ("300 x 300" );
148-
149- apply .addListener (SWT .Selection , e -> {
150- srcX = parse (tSrcX );
151- srcY = parse (tSrcY );
152- srcW = parse (tSrcW );
153- srcH = parse (tSrcH );
154-
155- dstX = parse (tDstX );
156- dstY = parse (tDstY );
157- dstW = parse (tDstW );
158- dstH = parse (tDstH );
159-
160- srcCanvas .redraw ();
161- dstCanvas .redraw ();
162- });
58+ Shell shell = new Shell ();
59+ shell .setLayout (new FillLayout ());
60+ shell .setText ("GC#drawImage Interactive" );
16361
62+ new CropImageView (shell , image );
16463 shell .setSize (1000 , 600 );
16564 shell .open ();
16665
@@ -173,19 +72,218 @@ public static void main(String[] args) {
17372 display .dispose ();
17473 }
17574
176- static Text field (Composite parent , String label , int value ) {
177- new Label (parent , SWT .NONE ).setText (label );
178- Text t = new Text (parent , SWT .BORDER );
179- t .setText (String .valueOf (value ));
180- t .setLayoutData (new GridData (70 , SWT .DEFAULT ));
181- return t ;
182- }
75+ private static class CropImageView extends Composite {
76+
77+ private Image image ;
78+ private int srcX , srcY , srcW , srcH ;
79+ private int dstX , dstY , dstW , dstH ;
80+ private float transformationScale ;
81+ private int transformationRotation ;
82+ private Text textSrcX , textSrcY , textSrcW , textSrcH ;
83+ private Text textDstX , textDstY , textDstW , textDstH ;
84+ private Text textScale ;
85+ private Slider rotationSlider ;
86+ private Canvas srcCanvas ;
87+ private Canvas dstCanvas ;
88+
89+ public CropImageView (Composite parent , Image image ) {
90+ super (parent , SWT .None );
91+ this .image = image ;
92+ init ();
93+ }
94+
95+ private void init () {
96+ setLayout (new GridLayout (2 , false ));
97+
98+ Rectangle imgBounds = image .getBounds ();
99+
100+ final int fixedDstW = imgBounds .width * 2 ;
101+ final int fixedDstH = imgBounds .height * 2 ;
102+ srcX = imgBounds .width / 2 ;
103+ srcY = imgBounds .height / 2 ;
104+ srcW = imgBounds .width / 2 ;
105+ srcH = imgBounds .height / 2 ;
106+
107+ dstX = 0 ;
108+ dstY = 0 ;
109+ dstW = imgBounds .width ;
110+ dstH = imgBounds .height ;
111+
112+ transformationScale = 1 ;
113+ transformationRotation = 0 ;
114+
115+ Group controls = new Group (this , SWT .NONE );
116+ controls .setText ("GC#drawImage Arguments" );
117+ controls .setLayoutData (new GridData (SWT .FILL , SWT .FILL , false , true ));
118+ controls .setLayout (new GridLayout (2 , false ));
119+
120+ textSrcX = field (controls , "srcX" , srcX );
121+ textSrcY = field (controls , "srcY" , srcY );
122+ textSrcW = field (controls , "srcWidth" , srcW );
123+ textSrcH = field (controls , "srcHeight" , srcH );
124+
125+ textDstX = field (controls , "destX" , dstX );
126+ textDstY = field (controls , "destY" , dstY );
127+ textDstW = field (controls , "destWidth" , dstW );
128+ textDstH = field (controls , "destHeight" , dstH );
129+
130+ textScale = field (controls , "Scale Factor" , transformationScale );
131+ rotationSlider = slider (controls , "Rotation" , transformationRotation , 361 );
132+
133+ Button apply = new Button (controls , SWT .PUSH );
134+ apply .setText ("Apply" );
135+ apply .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false , 2 , 1 ));
136+
137+ Composite draw = new Composite (this , SWT .NONE );
138+ draw .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
139+ draw .setLayout (new GridLayout (2 , true ));
140+
141+ srcCanvas = new Canvas (draw , SWT .BORDER );
142+ srcCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
143+ srcCanvas .addListener (SWT .Paint , e -> {
144+ try {
145+ GC gc = e .gc ;
146+ Rectangle ca = srcCanvas .getClientArea ();
147+
148+ int ix = (ca .width - imgBounds .width ) / 2 ;
149+ int iy = (ca .height - imgBounds .height ) / 2 ;
150+ Transform translationTransform = new Transform (getDisplay ());
151+ translationTransform .translate (ix , iy );
152+ gc .setTransform (translationTransform );
153+ gc .drawImage (image , 0 , 0 );
154+
155+ gc .setLineStyle (SWT .LINE_DASH );
156+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_BLACK ));
157+ gc .drawRectangle (0 , 0 , imgBounds .width , imgBounds .height );
158+
159+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_RED ));
160+ gc .setLineWidth (2 );
161+ gc .drawRectangle (srcX , srcY , srcW , srcH );
162+ } catch (Exception ex ) {
163+ MessageBox box = new MessageBox (getShell ());
164+ box .setText ("Invalid values" );
165+ box .setMessage ("There seem to be invalid value, the images cannot be drawn." );
166+ box .open ();
167+ }
168+ });
169+
170+ dstCanvas = new Canvas (draw , SWT .BORDER );
171+ dstCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
172+ dstCanvas .addListener (SWT .Paint , e -> {
173+ try {
174+ GC gc = e .gc ;
175+ Rectangle ca = dstCanvas .getClientArea ();
176+
177+ int px = (ca .width - fixedDstW ) / 2 ;
178+ int py = (ca .height - fixedDstH ) / 2 ;
179+ Transform translationTransform = new Transform (getDisplay ());
180+ translationTransform .translate (px + dstX , py + dstY );
181+
182+ translationTransform .translate (fixedDstW / 2f , fixedDstH / 2f );
183+ if (transformationScale > 1 ) {
184+ translationTransform .scale (transformationScale , transformationScale );
185+ }
186+ if (transformationRotation != 0 ) {
187+ translationTransform .rotate (transformationRotation );
188+ }
189+ translationTransform .translate (-fixedDstW / 2f , -fixedDstH / 2f );
190+ gc .setTransform (translationTransform );
191+
192+ Rectangle imageBounds = image .getBounds ();
193+ if (imageBounds .equals (new Rectangle (srcX , srcY , srcW , srcH ))) {
194+ gc .drawImage (image , 0 , 0 , dstW , dstH );
195+ } else {
196+ gc .drawImage (image , srcX , srcY , srcW , srcH , 0 , 0 , dstW , dstH );
197+ }
198+
199+ gc .setLineStyle (SWT .LINE_DASH );
200+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_BLACK ));
201+ gc .drawRectangle (0 , 0 , fixedDstW , fixedDstH );
202+
203+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_RED ));
204+ gc .setLineWidth (2 );
205+ gc .drawRectangle (0 , 0 , dstW , dstH );
206+ } catch (Exception ex ) {
207+ MessageBox box = new MessageBox (getShell ());
208+ box .setText ("Invalid values" );
209+ box .setMessage ("There seem to be invalid value, the images cannot be drawn." );
210+ box .open ();
211+ }
212+ });
213+
214+ Label srcLabel = new Label (draw , SWT .CENTER );
215+ srcLabel .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
216+ srcLabel .setText ("150 x 150" );
217+
218+ Label dstLabel = new Label (draw , SWT .CENTER );
219+ dstLabel .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
220+ dstLabel .setText ("300 x 300" );
221+
222+ apply .addListener (SWT .Selection , e -> {
223+ refreshView ();
224+ });
225+ }
183226
184- static int parse (Text t ) {
185- try {
186- return Integer .parseInt (t .getText ());
187- } catch (NumberFormatException e ) {
188- return 0 ;
227+ private void refreshView () {
228+ srcX = parseInt (textSrcX );
229+ srcY = parseInt (textSrcY );
230+ srcW = parseInt (textSrcW );
231+ srcH = parseInt (textSrcH );
232+
233+ dstX = parseInt (textDstX );
234+ dstY = parseInt (textDstY );
235+ dstW = parseInt (textDstW );
236+ dstH = parseInt (textDstH );
237+
238+ transformationScale = parseFloat (textScale );
239+ transformationRotation = rotationSlider .getSelection ();
240+
241+ srcCanvas .redraw ();
242+ dstCanvas .redraw ();
243+ }
244+
245+ Text field (Composite parent , String label , Number value ) {
246+ new Label (parent , SWT .NONE ).setText (label );
247+ Text t = new Text (parent , SWT .BORDER );
248+ t .setText (value .toString ());
249+ t .setLayoutData (new GridData (70 , SWT .DEFAULT ));
250+ return t ;
251+ }
252+
253+ Slider slider (Composite parent , String text , int value , int maxValue ) {
254+ Label label = new Label (parent , SWT .NONE );
255+ label .setText (text );
256+ label .setLayoutData (new GridData ());
257+
258+ Slider slider = new Slider (parent , SWT .BORDER );
259+ GridData gd = new GridData ();
260+ gd .grabExcessHorizontalSpace = true ;
261+ gd .horizontalSpan = 2 ;
262+ slider .setLayoutData (gd );
263+ slider .setValues (value , 0 , maxValue , 1 , 1 , 1 );
264+ slider .addSelectionListener (new SelectionAdapter () {
265+ @ Override
266+ public void widgetSelected (SelectionEvent e ) {
267+ refreshView ();
268+ }
269+ });
270+ return slider ;
271+ }
272+
273+ int parseInt (Text t ) {
274+ try {
275+ return Integer .parseInt (t .getText ());
276+ } catch (NumberFormatException e ) {
277+ return 0 ;
278+ }
279+ }
280+
281+ float parseFloat (Text t ) {
282+ try {
283+ return Float .parseFloat (t .getText ());
284+ } catch (NumberFormatException e ) {
285+ return 0 ;
286+ }
189287 }
190288 }
191289}
0 commit comments