1919/*
2020 * Demonstrates cropping and scaling of images using a GC
2121 *
22- * The GC provides two relevant drawImage methods: one that scales an entire
23- * image to a destination rectangle, and another that crops a source region and
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.
22+ * The GC provides three drawImage methods: one that draws an image at a target
23+ * destination, one that scales an entire image to a destination rectangle, and
24+ * another that crops a source region and scales it to the destination. The snippet
25+ * allows to select any source area of an image and draw it to a specific target
26+ * size. Additionally you can scale it additionally to the selected target size and
27+ * rotate the image.
28+ *
29+ * The snippet will draw the result with all three drawImage methods.
30+ * As not all methods will use all configuration option (e.g. only one methods supports
31+ * drawing a cropped part of an image), changing parameters does not always affect all
32+ * results.
2733 *
2834 * This snippet allows experimenting with different source and destination
2935 * values for the second method. Within the method, the GC receives the
@@ -60,7 +66,7 @@ public static void main(String[] args) {
6066 shell .setText ("GC#drawImage Interactive" );
6167
6268 new CropImageView (shell , image );
63- shell .setSize (1000 , 600 );
69+ shell .setSize (1000 , 800 );
6470 shell .open ();
6571
6672 while (!shell .isDisposed ()) {
@@ -76,15 +82,17 @@ private static class CropImageView extends Composite {
7682
7783 private Image image ;
7884 private int srcX , srcY , srcW , srcH ;
79- private int dstX , dstY , dstW , dstH ;
85+ private int dstW , dstH ;
8086 private float transformationScale ;
8187 private int transformationRotation ;
8288 private Text textSrcX , textSrcY , textSrcW , textSrcH ;
83- private Text textDstX , textDstY , textDstW , textDstH ;
89+ private Text textDstW , textDstH ;
8490 private Text textScale ;
8591 private Slider rotationSlider ;
8692 private Canvas srcCanvas ;
87- private Canvas dstCanvas ;
93+ private Canvas dstCanvas1 ;
94+ private Canvas dstCanvas2 ;
95+ private Canvas dstCanvas3 ;
8896
8997 public CropImageView (Composite parent , Image image ) {
9098 super (parent , SWT .None );
@@ -96,16 +104,11 @@ private void init() {
96104 setLayout (new GridLayout (2 , false ));
97105
98106 Rectangle imgBounds = image .getBounds ();
99-
100- final int fixedDstW = imgBounds .width * 2 ;
101- final int fixedDstH = imgBounds .height * 2 ;
102107 srcX = imgBounds .width / 2 ;
103108 srcY = imgBounds .height / 2 ;
104109 srcW = imgBounds .width / 2 ;
105110 srcH = imgBounds .height / 2 ;
106111
107- dstX = 0 ;
108- dstY = 0 ;
109112 dstW = imgBounds .width ;
110113 dstH = imgBounds .height ;
111114
@@ -122,8 +125,6 @@ private void init() {
122125 textSrcW = field (controls , "srcWidth" , srcW );
123126 textSrcH = field (controls , "srcHeight" , srcH );
124127
125- textDstX = field (controls , "destX" , dstX );
126- textDstY = field (controls , "destY" , dstY );
127128 textDstW = field (controls , "destWidth" , dstW );
128129 textDstH = field (controls , "destHeight" , dstH );
129130
@@ -138,7 +139,13 @@ private void init() {
138139 draw .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
139140 draw .setLayout (new GridLayout (2 , true ));
140141
141- srcCanvas = new Canvas (draw , SWT .BORDER );
142+ Group srcCanvasGroup = new Group (draw , SWT .NONE );
143+ srcCanvasGroup .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
144+ srcCanvasGroup .setLayout (new GridLayout (1 , true ));
145+ Label labelSrcCanvas = new Label (srcCanvasGroup , SWT .NONE );
146+ labelSrcCanvas .setText ("Source Image" );
147+ labelSrcCanvas .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
148+ srcCanvas = new Canvas (srcCanvasGroup , SWT .NONE );
142149 srcCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
143150 srcCanvas .addListener (SWT .Paint , e -> {
144151 try {
@@ -167,61 +174,108 @@ private void init() {
167174 }
168175 });
169176
170- dstCanvas = new Canvas (draw , SWT .BORDER );
177+ Group dstCanvas1Group = new Group (draw , SWT .NONE );
178+ dstCanvas1Group .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
179+ dstCanvas1Group .setLayout (new GridLayout (1 , true ));
180+ Label labelDstCanvas1 = new Label (dstCanvas1Group , SWT .WRAP );
181+ labelDstCanvas1 .setText ("GC#drawImage(Image, int, int) - Scale Factor and Rotation (no crop)" );
182+ labelDstCanvas1 .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
183+ dstCanvas1 = initDestinationCanvas (dstCanvas1Group , 1 , false );
184+
185+
186+ Group dstCanvas2Group = new Group (draw , SWT .NONE );
187+ dstCanvas2Group .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
188+ dstCanvas2Group .setLayout (new GridLayout (1 , true ));
189+ Label labelDstCanvas2 = new Label (dstCanvas2Group , SWT .WRAP );
190+ labelDstCanvas2 .setText ("GC#drawImage(Image, int, int, int, int) - destWidth, destHeight, Scale Factor and Rotation (no crop)" );
191+ labelDstCanvas2 .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
192+ dstCanvas2 = initDestinationCanvas (dstCanvas2Group , 2 , true );
193+
194+ Group dstCanvas3Group = new Group (draw , SWT .NONE );
195+ dstCanvas3Group .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
196+ dstCanvas3Group .setLayout (new GridLayout (1 , true ));
197+ Label labelDstCanvas3 = new Label (dstCanvas3Group , SWT .WRAP );
198+ labelDstCanvas3 .setText ("GC#drawImage(Image, int, int, int, int, int, int, int, int) - All" );
199+ labelDstCanvas3 .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
200+ dstCanvas3 = initDestinationCanvas (dstCanvas3Group , 3 , true );
201+
202+ apply .addListener (SWT .Selection , e -> refreshView ());
203+ }
204+
205+ private Canvas initDestinationCanvas (Composite parent , int drawingMode , boolean scalableAPI ) {
206+ Canvas dstCanvas = new Canvas (parent , SWT .NONE );
171207 dstCanvas .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
172208 dstCanvas .addListener (SWT .Paint , e -> {
173209 try {
174210 GC gc = e .gc ;
175211 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 );
212+ Rectangle imgBounds = image .getBounds ();
213+ switch (drawingMode ) {
214+ case 1 : {
215+ float imageBoundsX = imgBounds .width * transformationScale ;
216+ float imageBoundsY = imgBounds .height * transformationScale ;
217+ int px = Math .round ((ca .width - imgBounds .width * transformationScale ) / 2f );
218+ int py = Math .round ((ca .height - imgBounds .height * transformationScale ) / 2f );
219+ prepareTransform (gc , px , py , imageBoundsX , imageBoundsY );
220+ gc .drawImage (image , 0 , 0 );
221+ gc .setLineStyle (SWT .LINE_DASH );
222+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_BLACK ));
223+ gc .drawRectangle (0 , 0 , imgBounds .width , imgBounds .height );
224+ break ;
225+ }
226+ case 2 : {
227+ float imageBoundsX = dstW * transformationScale ;
228+ float imageBoundsY = dstH * transformationScale ;
229+ int px = Math .round ((ca .width - dstW * transformationScale ) / 2f );
230+ int py = Math .round ((ca .height - dstH * transformationScale ) / 2f );
231+ prepareTransform (gc , px , py , imageBoundsX , imageBoundsY );
232+ gc .drawImage (image , 0 , 0 , dstW , dstH );
233+ gc .setLineStyle (SWT .LINE_DASH );
234+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_BLACK ));
235+ gc .drawRectangle (0 , 0 , dstW , dstH );
236+ break ;
237+ }
238+ case 3 : {
239+ float imageBoundsX = dstW * transformationScale ;
240+ float imageBoundsY = dstH * transformationScale ;
241+ int px = Math .round ((ca .width - dstW * transformationScale ) / 2f );
242+ int py = Math .round ((ca .height - dstH * transformationScale ) / 2f );
243+ prepareTransform (gc , px , py , imageBoundsX , imageBoundsY );
244+ gc .drawImage (image , srcX , srcY , srcW , srcH , 0 , 0 , dstW , dstH );
245+ gc .setLineStyle (SWT .LINE_DASH );
246+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_BLACK ));
247+ gc .drawRectangle (0 , 0 , dstW , dstH );
248+ gc .setForeground (getDisplay ().getSystemColor (SWT .COLOR_RED ));
249+ gc .setLineWidth (1 );
250+ gc .drawRectangle (0 , 0 , dstW , dstH );
251+ break ;
252+ }
253+ default :
254+ throw new IllegalArgumentException ("Unexpected value: " + drawingMode );
188255 }
189- translationTransform .translate (-fixedDstW / 2f , -fixedDstH / 2f );
190- gc .setTransform (translationTransform );
191256
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- }
198257
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 );
206258 } catch (Exception ex ) {
207259 MessageBox box = new MessageBox (getShell ());
208260 box .setText ("Invalid values" );
209261 box .setMessage ("There seem to be invalid value, the images cannot be drawn." );
210262 box .open ();
211263 }
212264 });
265+ return dstCanvas ;
266+ }
213267
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- } );
268+ private void prepareTransform ( GC gc , int offestX , int offsetY , float imageBoundsX , float imageBoundsY ) {
269+ Transform translationTransform = new Transform ( getDisplay ( ));
270+ translationTransform . translate ( offestX + imageBoundsX / 2 , offsetY + imageBoundsY / 2 );
271+ if ( transformationScale > 1 ) {
272+ translationTransform . scale ( transformationScale , transformationScale );
273+ }
274+ if ( transformationRotation != 0 ) {
275+ translationTransform . rotate ( transformationRotation );
276+ }
277+ translationTransform . translate (- imageBoundsX / 2 / transformationScale , - imageBoundsY / 2 / transformationScale );
278+ gc . setTransform ( translationTransform );
225279 }
226280
227281 private void refreshView () {
@@ -230,16 +284,16 @@ private void refreshView() {
230284 srcW = parseInt (textSrcW );
231285 srcH = parseInt (textSrcH );
232286
233- dstX = parseInt (textDstX );
234- dstY = parseInt (textDstY );
235287 dstW = parseInt (textDstW );
236288 dstH = parseInt (textDstH );
237289
238290 transformationScale = parseFloat (textScale );
239291 transformationRotation = rotationSlider .getSelection ();
240292
241293 srcCanvas .redraw ();
242- dstCanvas .redraw ();
294+ dstCanvas1 .redraw ();
295+ dstCanvas2 .redraw ();
296+ dstCanvas3 .redraw ();
243297 }
244298
245299 Text field (Composite parent , String label , Number value ) {
0 commit comments