|
| 1 | +/******************************************************************************* |
| 2 | + * Copyright (c) 2026 Yatta Solutions and others. |
| 3 | + * |
| 4 | + * This program and the accompanying materials |
| 5 | + * are made available under the terms of the Eclipse Public License 2.0 |
| 6 | + * which accompanies this distribution, and is available at |
| 7 | + * https://www.eclipse.org/legal/epl-2.0/ |
| 8 | + * |
| 9 | + * SPDX-License-Identifier: EPL-2.0 |
| 10 | + *******************************************************************************/ |
| 11 | +package org.eclipse.swt.snippets; |
| 12 | + |
| 13 | +import org.eclipse.swt.*; |
| 14 | +import org.eclipse.swt.graphics.*; |
| 15 | +import org.eclipse.swt.layout.*; |
| 16 | +import org.eclipse.swt.widgets.*; |
| 17 | + |
| 18 | +/* |
| 19 | + * Demonstrates cropping and scaling of images using a GC |
| 20 | + * |
| 21 | + * The GC provides two relevant drawImage methods: one that scales an entire |
| 22 | + * image to a destination rectangle, and another that crops a source region and |
| 23 | + * scales it to the destination. |
| 24 | + * |
| 25 | + * This snippet allows experimenting with different source and destination |
| 26 | + * values for the second method. Within the method, the GC receives the |
| 27 | + * best-fitting image handle based on the current monitor zoom and image scaling |
| 28 | + * factor, minimizing native resampling. |
| 29 | + * |
| 30 | + * For a list of all SWT example snippets see |
| 31 | + * http://www.eclipse.org/swt/snippets/ |
| 32 | + */ |
| 33 | +public class Snippet389 { |
| 34 | + |
| 35 | + private static final String IMAGE_100 = "workset_wiz150.png"; |
| 36 | + private static final String IMAGE_200 = "workset_wiz300.png"; |
| 37 | + private static final String IMAGES_ROOT = "resources/Snippet389/"; |
| 38 | + |
| 39 | + private static final String IMAGE_PATH_100 = IMAGES_ROOT + IMAGE_100; |
| 40 | + private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200; |
| 41 | + |
| 42 | + static int srcX, srcY, srcW, srcH; |
| 43 | + static int dstX, dstY, dstW, dstH; |
| 44 | + |
| 45 | + public static void main(String[] args) { |
| 46 | + |
| 47 | + ImageFileNameProvider filenameProvider = zoom -> { |
| 48 | + switch (zoom) { |
| 49 | + case 100: |
| 50 | + return IMAGE_PATH_100; |
| 51 | + case 200: |
| 52 | + return IMAGE_PATH_200; |
| 53 | + default: |
| 54 | + return null; |
| 55 | + } |
| 56 | + }; |
| 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 | + |
| 63 | + 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 | + }); |
| 163 | + |
| 164 | + shell.setSize(1000, 600); |
| 165 | + shell.open(); |
| 166 | + |
| 167 | + while (!shell.isDisposed()) { |
| 168 | + if (!display.readAndDispatch()) |
| 169 | + display.sleep(); |
| 170 | + } |
| 171 | + |
| 172 | + image.dispose(); |
| 173 | + display.dispose(); |
| 174 | + } |
| 175 | + |
| 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 | + } |
| 183 | + |
| 184 | + static int parse(Text t) { |
| 185 | + try { |
| 186 | + return Integer.parseInt(t.getText()); |
| 187 | + } catch (NumberFormatException e) { |
| 188 | + return 0; |
| 189 | + } |
| 190 | + } |
| 191 | +} |
0 commit comments