Java: create shadow effect on image

后端 未结 2 1728
南笙
南笙 2020-12-10 09:20

I\'m trying to create a shadow effect (with java) on an image.

I\'ve seen multiple related questions and I\'ve implemented several of the suggested solutions. Unfort

相关标签:
2条回答
  • 2020-12-10 10:22

    The over all theory is simple. Basically, you need to generate a mask of the image (using a AlphaComposite and fill that resulting image with the color you want (also using an AlphaComposite. This, of course, all works on the alpha channel of the image...

    Once you have that mask, you need to combine the two images (overlaying the original image with the masked image)

    This examples make use of JHLabs filters to supply the blur...

    enter image description here

    public class TestImageDropShadow {
    
        public static void main(String[] args) {
            new TestImageDropShadow();
        }
    
        public TestImageDropShadow() {
            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 ImagePane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class ImagePane extends JPanel {
    
            private BufferedImage background;
    
            public ImagePane() {
                try {
                    BufferedImage master = ImageIO.read(getClass().getResource("/Scaled.png"));
                    background = applyShadow(master, 5, Color.BLACK, 0.5f);
                } catch (IOException ex) {
                    Logger.getLogger(TestImageDropShadow.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (background != null) {
                    int x = (getWidth() - background.getWidth()) / 2;
                    int y = (getHeight() - background.getHeight()) / 2;
                    g.drawImage(background, x, y, this);
                }
            }
    
        }
    
        public static void applyQualityRenderingHints(Graphics2D g2d) {
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        }
    
        public static BufferedImage createCompatibleImage(int width, int height) {
            return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        }
    
        public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
            BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
            image.coerceData(true);
            return image;
        }
    
        public static BufferedImage createCompatibleImage(BufferedImage image) {
            return createCompatibleImage(image, image.getWidth(), image.getHeight());
        }
    
        public static BufferedImage createCompatibleImage(BufferedImage image,
                int width, int height) {
            return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency());
        }
    
        public static GraphicsConfiguration getGraphicsConfiguration() {
            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        }
    
        public static BufferedImage generateMask(BufferedImage imgSource, Color color, float alpha) {
            int imgWidth = imgSource.getWidth();
            int imgHeight = imgSource.getHeight();
    
            BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight);
            Graphics2D g2 = imgBlur.createGraphics();
            applyQualityRenderingHints(g2);
    
            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 imgBlur;
        }
    
        public static BufferedImage generateBlur(BufferedImage imgSource, int size, Color color, float alpha) {
            GaussianFilter filter = new GaussianFilter(size);
    
            int imgWidth = imgSource.getWidth();
            int imgHeight = imgSource.getHeight();
    
            BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight);
            Graphics2D g2 = imgBlur.createGraphics();
            applyQualityRenderingHints(g2);
    
            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();
    
            imgBlur = filter.filter(imgBlur, null);
    
            return imgBlur;
        }
    
        public static BufferedImage applyShadow(BufferedImage imgSource, int size, Color color, float alpha) {
            BufferedImage result = createCompatibleImage(imgSource, imgSource.getWidth() + (size * 2), imgSource.getHeight() + (size * 2));
            Graphics2D g2d = result.createGraphics();
            g2d.drawImage(generateShadow(imgSource, size, color, alpha), size, size, null);
            g2d.drawImage(imgSource, 0, 0, null);
            g2d.dispose();
    
            return result;
        }
    
        public static BufferedImage generateShadow(BufferedImage imgSource, int size, Color color, float alpha) {
            int imgWidth = imgSource.getWidth() + (size * 2);
            int imgHeight = imgSource.getHeight() + (size * 2);
    
            BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight);
            Graphics2D g2 = imgMask.createGraphics();
            applyQualityRenderingHints(g2);
    
            int x = Math.round((imgWidth - imgSource.getWidth()) / 2f);
            int y = Math.round((imgHeight - imgSource.getHeight()) / 2f);
            g2.drawImage(imgSource, x, y, null);
            g2.dispose();
    
            // ---- Blur here ---
    
            BufferedImage imgGlow = generateBlur(imgMask, (size * 2), color, alpha);
    
            return imgGlow;
        }
    
        public static Image applyMask(BufferedImage sourceImage, BufferedImage maskImage) {
            return applyMask(sourceImage, maskImage, AlphaComposite.DST_IN);
        }
    
        public static BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
            BufferedImage maskedImage = null;
            if (sourceImage != null) {
    
                int width = maskImage.getWidth(null);
                int height = maskImage.getHeight(null);
    
                maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                Graphics2D mg = maskedImage.createGraphics();
    
                int x = (width - sourceImage.getWidth(null)) / 2;
                int y = (height - sourceImage.getHeight(null)) / 2;
    
                mg.drawImage(sourceImage, x, y, null);
                mg.setComposite(AlphaComposite.getInstance(method));
    
                mg.drawImage(maskImage, 0, 0, null);
    
                mg.dispose();
            }
            return maskedImage;
        }
    }
    
    0 讨论(0)
  • 2020-12-10 10:22

    This is my Version:

    private static Image dropShadow(BufferedImage img) {
        // a filter which converts all colors except 0 to black
        ImageProducer prod = new FilteredImageSource(img.getSource(), new RGBImageFilter() {
            @Override
            public int filterRGB(int x, int y, int rgb) {
                if (rgb == 0)
                    return 0;
                else
                    return 0xff000000;
            }
        });
        // create whe black image
        Image shadow = Toolkit.getDefaultToolkit().createImage(prod);
    
        // result
        BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
        Graphics2D g = (Graphics2D) result.getGraphics();
    
        // draw shadow with offset
        g.drawImage(shadow, 10, 0, null);
        // draw original image
        g.drawImage(img, 0, 0, null);
    
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题