Могу ли я иметь изображение альфа исчезать слева направо в Java?

Я делаю игру и хочу, чтобы одно изображение "исчезало" слева направо, причем левая часть изображения имеет альфа-коэффициент 1,0, а правая часть имеет альфа-коэффициент 0,0. (примечание: я не хочу, чтобы он менял то, как он выглядит со временем, например, постепенно исчезал, а просто исчезал слева направо и оставался постоянным). Ниже приведена попытка нарисовать то, что я хочу, чтобы конечный результат выглядел так:

lll lll ll ll l l  l    l            l
lll lll ll ll l l  l    l            l
lll lll ll ll l l  l    l            l
lll lll ll ll l l  l    l            l
lll lll ll ll l l  l    l            l
lll lll ll ll l l  l    l            l

Где плотности "я" представляют альфа

В настоящее время я использую буферизованные изображения TYPE_INT_RGB, и хотел бы сохранить это, если это возможно.

Существуют ли какие-либо встроенные Java-классы, которые могут помочь мне сделать это, или, по крайней мере, (относительно легкий) способ сделать это сам, что я просто не могу понять?


РЕДАКТИРОВАТЬ: я не хочу иметь непрозрачные рамки любого рода. Я хочу нарисовать один BufferedImage (с альфа-градиентом) на другой BufferedImage.

1 ответ

Решение

Основная идея состоит в том, чтобы применить AlphaComposite замаскировать оригинальное изображение, которое было заполнено LinearGradientPaint

Итак, начнем с загрузки исходного изображения...

BufferedImage original = ImageIO.read(new File("/an/image/somewhere"));

Затем мы создаем маскирующее изображение того же размера...

BufferedImage alphaMask = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_ARGB);

Затем мы заполняем маскирующее изображение LinearGradientPaint...

Graphics2D g2d = alphaMask.createGraphics();
LinearGradientPaint lgp = new LinearGradientPaint(
        new Point(0, 0), 
        new Point(alphaMask.getWidth(), 0), 
        new float[]{0, 1}, 
        new Color[]{new Color(0, 0, 0, 255), new Color(0, 0, 0 , 0)});
g2d.setPaint(lgp);
g2d.fillRect(0, 0, alphaMask.getWidth(), alphaMask.getHeight());
g2d.dispose();

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

Затем мы применяем маску...

BufferedImage faded = applyMask(original, alphaMask, AlphaComposite.DST_IN);

Который на самом деле вызывает этот служебный метод...

public static BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {

    BufferedImage maskedImage = null;
    if (sourceImage != null) {

        int width = maskImage.getWidth();
        int height = maskImage.getHeight();

        maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D mg = maskedImage.createGraphics();

        int x = (width - sourceImage.getWidth()) / 2;
        int y = (height - sourceImage.getHeight()) / 2;

        mg.drawImage(sourceImage, x, y, null);
        mg.setComposite(AlphaComposite.getInstance(method));

        mg.drawImage(maskImage, 0, 0, null);

        mg.dispose();
    }

    return maskedImage;

}

Это в основном использует "назначение в" AlphaComposite нанести маску на исходное изображение, в результате чего...

(оригинал слева, альфа справа)

Альфа

И чтобы убедиться в этом, я изменил цвет фона панели содержимого фрейма на RED

введите описание изображения здесь

Другие вопросы по тегам