javaeclipseimageswt

How to scale a transparent org.eclipse.swt.graphics.Image, loaded from a PNG; Java


I have an org.eclipse.swt.graphics.Image, loaded from a PNG, and want to scale it in high quality (antialiasing, interpolation). But I do not want to lose transparency and get just a white background. (I need this Image to put it on an org.eclipse.swt.widgets.Label .)

Does anybody know how to do that? Thank you!


Solution

  • Based on Mark's answer I found a better solution without the "hacky bit": first copy the alphaData from the origin then use GC to scale the image.

    public static Image scaleImage(final Device device, final Image orig, final int scaledWidth, final int scaledHeight) {     
        final Rectangle origBounds = orig.getBounds();     
        if (origBounds.width == scaledWidth && origBounds.height == scaledHeight) {     
            return orig;     
        }     
    
        final ImageData origData = orig.getImageData();     
        final ImageData destData = new ImageData(scaledWidth, scaledHeight, origData.depth, origData.palette);     
        if (origData.alphaData != null) {     
            destData.alphaData = new byte[destData.width * destData.height];     
            for (int destRow = 0; destRow < destData.height; destRow++) {     
                for (int destCol = 0; destCol < destData.width; destCol++) {     
                    final int origRow = destRow * origData.height / destData.height;     
                    final int origCol = destCol * origData.width / destData.width;     
                    final int o = origRow * origData.width + origCol;     
                    final int d = destRow * destData.width + destCol;     
                    destData.alphaData[d] = origData.alphaData[o];     
                }     
            }     
        }     
    
        final Image dest = new Image(device, destData);     
    
        final GC gc = new GC(dest);     
        gc.setAntialias(SWT.ON);     
        gc.setInterpolation(SWT.HIGH);     
        gc.drawImage(orig, 0, 0, origBounds.width, origBounds.height, 0, 0, scaledWidth, scaledHeight);     
        gc.dispose();
    
        return dest;
    }
    

    This way we don't have to make assumptions about the underlying ImageData.