From e57f0db2e51b3d4c185b52546536394b380dced7 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 1 Oct 2025 21:13:58 +0200 Subject: [PATCH] Add snippet for demonstrating options to programmatically create images With the implementation of monitor-specific UI scaling on Windows, an SWT application does not have a static zoom anymore. The zoom will be specific for each shell and the monitor it is currently placed on. As a consequence, when programmatically creating an image, the target zoom at which it will be used is not known when creating the image anymore. Instead, it will depend on the context in which the image is used later on. There are multiple options how to achieve that such an image will still be rendered at the according zoom in a sharp way instead of rendering it at an arbitrary zoom and then scaling it in a blurry way. This snippet demonstrates these different options and also a common way for programmatic image creation that will lead to blurry results. --- examples/org.eclipse.swt.snippets/Snippets.md | 1 + .../previews/Snippet387.png | Bin 0 -> 15382 bytes .../org/eclipse/swt/snippets/Snippet387.java | 112 ++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 examples/org.eclipse.swt.snippets/previews/Snippet387.png create mode 100644 examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet387.java diff --git a/examples/org.eclipse.swt.snippets/Snippets.md b/examples/org.eclipse.swt.snippets/Snippets.md index 4251fb9d051..042beb3cd13 100644 --- a/examples/org.eclipse.swt.snippets/Snippets.md +++ b/examples/org.eclipse.swt.snippets/Snippets.md @@ -217,6 +217,7 @@ To contribute a new snippet, [create a snippet contribution as a pull request](h - [draw a disabled/grayed image at various zoom levels](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet382.png "Preview for Snippet 382") - [compare algorithms for rendering disabled images](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet384.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet384.png "Preview for Snippet 384") - [draw an image with watermark using ImageGcProvider](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet385.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet385.png "Preview for Snippet 385") +- [options for programmatically creating an image](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet387.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet387.png "Preview for Snippet 387") ### **ImageData** - [display an animated GIF](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet141.java) diff --git a/examples/org.eclipse.swt.snippets/previews/Snippet387.png b/examples/org.eclipse.swt.snippets/previews/Snippet387.png new file mode 100644 index 0000000000000000000000000000000000000000..a2adfe8fabd013654216b8488a9d6976f2a2c96c GIT binary patch literal 15382 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 + * When creating an image programmatically, it is important to use an + * appropriate way of doing that when at the time of image creation it is not + * yet known at which zoom the image will be used. This is particularly the case + * when using monitor-specific scaling on Windows. + *

+ * There are two general options how to programmatically create an image: + *

    + *
  • {@link ImageGcDrawer}: create an image with an {@link ImageGcDrawer}; + * preferred way as the drawer will be called with the requested zoom when + * needed + *
  • {@link GC} on image: create an image with fixed dimensions and create a + * {@link GC} for the image to drawn on; this is the legacy way of drawing an + * image and should only be used if the whole drawing logic cannot be wrapped + * into an {@link ImageGcDrawer} but the {@link GC} may be passed around to + * collect drawing contributions from different places + *
+ * When using the second approach creating a {@link GC} on top of an image, it + * is important to not dispose the GC before using the image, as in that case + * the Windows implementation of an image can request its regeneration at the + * desired zoom from the GC. If the GC is disposed before the image is used at + * desired zoom, it may need to blurry-scale any existing drawing result to the + * requested zoom instead of sharply rendering it at that zoom. + *

+ * This snippet demonstrates both proper usages of the above mentioned options + * as well as a usage that disposes the GC before consuming the image at the + * desired zoom, leading to a blurry result. To see such a bad result, the + * snippet needs to be executed on Windows and has to be moved between monitors + * with different monitor zooms. + *

+ * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + *

+ */ +public class Snippet387 { + + private static final int PADDING = 5; + private static final int IMAGE_WIDTH = 270; + private static final int IMAGE_HEIGHT = 50; + + public static void main(String[] args) { + activateMonitorSpecificScaling(); + + Display display = new Display(); + Shell shell = new Shell(display); + shell.setText("Programmatic Images"); + shell.setSize(IMAGE_WIDTH + 2 * PADDING + 20, 3 * IMAGE_HEIGHT + 4 * PADDING + 40); + + Image staticImage = createStaticImage(display, "Static Image with disposed GC", true); + Image staticImageUndisposedGC = createStaticImage(display, "Static Image with non-disposed GC", false); + Image dynamicImage = createDynamicImage(display, "Dynamic Image"); + + shell.addPaintListener(event -> { + GC gc = event.gc; + gc.drawImage(staticImage, PADDING, PADDING); + gc.drawImage(staticImageUndisposedGC, PADDING, 2 * PADDING + IMAGE_HEIGHT); + gc.drawImage(dynamicImage, PADDING, 3 * PADDING + 2 * IMAGE_HEIGHT); + }); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + + private static void activateMonitorSpecificScaling() { + System.setProperty("swt.autoScale.updateOnRuntime", "true"); + } + + private static Image createStaticImage(Display display, String text, boolean disposeGC) { + Image staticImage = new Image(display, IMAGE_WIDTH, IMAGE_HEIGHT); + GC imageGC = new GC(staticImage); + try { + drawImageContent(imageGC, text, IMAGE_WIDTH, IMAGE_HEIGHT); + } finally { + if (disposeGC) { + imageGC.dispose(); + } + } + return staticImage; + } + + private static Image createDynamicImage(Display display, String text) { + return new Image(display, (gc, w, h) -> drawImageContent(gc, text, w, h), IMAGE_WIDTH, IMAGE_HEIGHT); + } + + private static void drawImageContent(GC gc, String text, int width, int height) { + gc.drawRectangle(0, 0, width - 1, height - 1); + gc.drawText(text, PADDING, PADDING); + } + +} \ No newline at end of file