Использование прозрачного изображения с использованием Java SWT

Как создать полностью прозрачное SWT-изображение в памяти и нарисовать черную линию с поддержкой antialias?

Я ожидаю, что результат будет включать только черный цвет и альфа-значения от 0 до 255 из-за антиалиасов...

Я googled и пробовал все, что мог... это вообще возможно?

Ответ 1

Вот как я это сделал и он работает:

    Image src = new Image(null, 16, 16);        
    ImageData imageData = src.getImageData();
    imageData.transparentPixel = imageData.getPixel(0, 0);
    src.dispose();
    Image icon = new Image(null, imageData);
    //draw on the icon with gc

Ответ 2

Я сделал это, выделив ImageData, сделав его прозрачным, затем создав Image из данных:

static Image createTransparentImage(Display display, int width, int height) {
    // allocate an image data
    ImageData imData = new ImageData(width, height, 24, new PaletteData(0xff0000,0x00ff00, 0x0000ff));
    imData.setAlpha(0, 0, 0); // just to force alpha array allocation with the right size
    Arrays.fill(imData.alphaData, (byte) 0); // set whole image as transparent

    // Initialize image from transparent image data
    return new Image(display, imData);
}

Ответ 3

Мне удалось выполнить эту работу, хотя она немного взломана:

Display display = Display.getDefault();

int width = 10;
int height = 10;

Image canvas = new Image(display, width, height);

GC gc = new GC(canvas);

gc.setAntialias(SWT.ON);

// This sets the alpha on the entire canvas to transparent
gc.setAlpha(0);
gc.fillRectangle(0, 0, width, height);

// Reset our alpha and draw a line
gc.setAlpha(255);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
gc.drawLine(0, 0, width, height);

// We're done with the GC, so dispose of it
gc.dispose();

ImageData canvasData = canvas.getImageData();
canvasData.alphaData = new byte[width * height];

// This is the hacky bit that is making assumptions about
// the underlying ImageData.  In my case it is 32 bit data
// so every 4th byte in the data array is the alpha for that
// pixel...
for (int idx = 0; idx < (width * height); idx++) {
    int coord = (idx * 4) + 3;
    canvasData.alphaData[idx] = canvasData.data[coord];
}

// Now that we've set the alphaData, we can create our
// final image
Image finalImage = new Image(canvasData);

// And get rid of the canvas
canvas.dispose();

После этого finalImage можно вставить в GC с drawImage, и прозрачные части будут соблюдены.

Ответ 4

Чтобы масштабировать с прозрачностью, я обнаружил, что мне нужно вручную задать массив альфа-байтов, как показано ниже. Таким образом, альфа заканчивается сглаживанием с ближайшим соседством.

public static Image scaleImage(Device device, Image orig, int scaledWidth, int scaledHeight) {
    Rectangle origBounds = orig.getBounds();
    if (origBounds.width == scaledWidth && origBounds.height == scaledHeight) {
        return orig;
    }

    ImageData origData = orig.getImageData();
    ImageData imData = new ImageData(scaledWidth, scaledHeight, origData.depth, origData.palette);
    if (origData.alphaData != null) {
        imData.alphaData = new byte[imData.width * imData.height];
        for (int row = 0; row < imData.height; row++) {
            for (int col = 0; col < imData.width; col++) {
                int origRow = row * origData.height / imData.height;
                int origCol = col * origData.width / imData.width;
                byte origAlpha = origData.alphaData[origRow * origData.width + origCol];
                imData.alphaData[row * imData.width + col] = origAlpha;
            }
        }
    }
    final Image scaled = new Image(device, imData);
    GC gc = new GC(scaled);
    gc.setAntialias(SWT.ON);
    gc.setInterpolation(SWT.HIGH);
    gc.setBackground(device.getSystemColor(SWT.COLOR_WHITE));
    gc.fillRectangle(0, 0, scaledWidth, scaledHeight);
    gc.drawImage(orig, 0, 0, origBounds.width, origBounds.height, 0, 0, scaledWidth, scaledHeight);
    gc.dispose();
    return scaled;
}