Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何重叠java图形和图像并使其看起来美观?_Java_Image_Swing_Graphics - Fatal编程技术网

如何重叠java图形和图像并使其看起来美观?

如何重叠java图形和图像并使其看起来美观?,java,image,swing,graphics,Java,Image,Swing,Graphics,我的问题很具体。我正在开发一个游戏,里面有一个药瓶可以从敌人身上掉落。药水罐的图像是一个透明的罐,有黑色边框和不透明的白色背景。之所以有不透明的白色背景,是因为我还需要画罐子里还有多少药水。我目前的做法是: 画一个高度为H的矩形,表示还有多少药剂 在矩形顶部绘制药剂罐图像 因此,这将与绘制的丑陋的红色矩形重叠,表示药剂的透明区域周围有不透明的白色空间,表示药剂的剩余量。以下是结果的图像: 问题的出现是因为药瓶在游戏中看起来确实很糟糕。白色背景看起来很恐怖 我的问题是:有没有办法去除不透明的白色

我的问题很具体。我正在开发一个游戏,里面有一个药瓶可以从敌人身上掉落。药水罐的图像是一个透明的罐,有黑色边框和不透明的白色背景。之所以有不透明的白色背景,是因为我还需要画罐子里还有多少药水。我目前的做法是:

  • 画一个高度为H的矩形,表示还有多少药剂
  • 在矩形顶部绘制药剂罐图像
  • 因此,这将与绘制的丑陋的红色矩形重叠,表示药剂的透明区域周围有不透明的白色空间,表示药剂的剩余量。以下是结果的图像:

    问题的出现是因为药瓶在游戏中看起来确实很糟糕。白色背景看起来很恐怖


    我的问题是:有没有办法去除不透明的白色背景,同时仍然能够“填充”图像定义的药瓶空间?

    是的。您需要使用算法来执行精灵的绘图区域的外部

    基本上,您可以创建原始图像的“遮罩”,该遮罩可以从图像的非不透明部分生成

    所以我创建了两个药剂图像(当然你可以使用一张精灵纸)。一个中心不透明,另一个透明(只是轮廓)

    由此,我能够生成第一幅图像的遮罩(以我想要的颜色),使用子图像减少我想要使用的图像数量,然后渲染它和轮廓

    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GraphicsConfiguration;
    import java.awt.GraphicsEnvironment;
    import java.awt.RenderingHints;
    import java.awt.Transparency;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestOverlay {
    
        public static void main(String[] args) {
            new TestOverlay();
        }
    
        public TestOverlay() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage potionBase;
            private BufferedImage potionOutline;
            private float value = 1f;
    
            public TestPane() {
                try {
                    potionBase = ImageIO.read(new File("Potion.png"));
                    potionOutline = ImageIO.read(new File("PotionOutline.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
    
                Timer timer = new Timer(40, new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        value = value - 0.01f;
                        if (value < 0) {
                            value = 1f;
                        }
                        repaint();
                    }
                });
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return potionBase == null ? super.getPreferredSize() : new Dimension(potionBase.getWidth(), potionBase.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                BufferedImage mask = generateMask(potionBase, Color.RED, 1f);
    
                int y = (int) (mask.getHeight() * (1f - value));
                if (y < mask.getHeight()) {
    
                    mask = mask.getSubimage(0, y, mask.getWidth(), mask.getHeight() - y);
    
                }
    
                int x = (getWidth() - mask.getWidth()) / 2;
                y = y + ((getHeight() - potionOutline.getHeight()) / 2);
    
                g2d.drawImage(mask, x, y, this);
                y = ((getHeight() - potionOutline.getHeight()) / 2);
                g2d.drawImage(potionOutline, x, y, this);
                g2d.dispose();
            }
    
        }
    
        public static BufferedImage generateMask(BufferedImage imgSource, Color color, float alpha) {
    
            int imgWidth = imgSource.getWidth();
            int imgHeight = imgSource.getHeight();
    
            BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
            Graphics2D g2 = imgMask.createGraphics();
    
            g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
    
            g2.drawImage(imgSource, 0, 0, null);
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
            g2.setColor(color);
    
            g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight());
            g2.dispose();
    
            return imgMask;
    
        }
    
        public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
    
            BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
            image.coerceData(true);
            return image;
    
        }
    
        public static GraphicsConfiguration getGraphicsConfiguration() {
    
            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    
        }
    
    }
    

    导入java.awt.AlphaComposite;
    导入java.awt.BorderLayout;
    导入java.awt.Color;
    导入java.awt.Dimension;
    导入java.awt.EventQueue;
    导入java.awt.Graphics;
    导入java.awt.Graphics2D;
    导入java.awt.GraphicsConfiguration;
    导入java.awt.GraphicsEnvironment;
    导入java.awt.RenderingHints;
    导入java.awt.Transparency;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.image.buffereImage;
    导入java.io.File;
    导入java.io.IOException;
    导入javax.imageio.imageio;
    导入javax.swing.JFrame;
    导入javax.swing.JPanel;
    导入javax.swing.Timer;
    导入javax.swing.UIManager;
    导入javax.swing.UnsupportedLookAndFeelException;
    公共类测试覆盖{
    公共静态void main(字符串[]args){
    新的TestOverlay();
    }
    公共TestOverlay(){
    invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    试一试{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
    }
    JFrame=新JFrame(“测试”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(新的BorderLayout());
    frame.add(newtestpane());
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    }
    });
    }
    公共类TestPane扩展了JPanel{
    私有缓存映像库;
    专用缓冲区映像potionOutline;
    私有浮动值=1f;
    公共测试窗格(){
    试一试{
    potionBase=ImageIO.read(新文件(“Potion.png”);
    potionOutline=ImageIO.read(新文件(“potionOutline.png”);
    }捕获(IOEX异常){
    例如printStackTrace();
    }
    计时器计时器=新计时器(40,新ActionListener(){
    @凌驾
    已执行的公共无效操作(操作事件e){
    值=值-0.01f;
    如果(值<0){
    数值=1f;
    }
    重新油漆();
    }
    });
    timer.start();
    }
    @凌驾
    公共维度getPreferredSize(){
    return potionBase==null?super.getPreferredSize():新维度(potionBase.getWidth(),potionBase.getHeight());
    }
    @凌驾
    受保护组件(图形g){
    超级组件(g);
    Graphics2D g2d=(Graphics2D)g.create();
    BuffereImage掩码=生成掩码(potionBase,颜色为红色,1f);
    int y=(int)(mask.getHeight()*(1f-value));
    if(y