2

画像に (Java を使用して) 影の効果を作成しようとしています。

関連する複数の質問を見て、提案された解決策のいくつかを実装しました。残念ながら、私は常に同じ問題を抱えています。影の効果により、画像全体が灰色 (つまり、影の色) に再描画されるため、元の画像が表示されなくなります。

私がテストしたコードの例 (JIDE の自由に利用できるライブラリに基づく):

ShadowFactory sf = new ShadowFactory(2, 0.5f, Color.black);
ImageIO.write(sf.createShadow(ImageIO.read(new File("c:\\out2.png"))), "png", new File("c:\\out3.png"));

これを複数のソース ファイル (out2.png) でテストしたことは言うまでもありません。

私は無知です:ヒント/ヘルプは大歓迎です。

4

2 に答える 2

9

全体的な理論は単純です。基本的に、画像のマスクを生成する必要があります ( を使用し、AlphaCompositeその結果の画像を必要な色で塗りつぶします (また を使用しAlphaCompositeます。もちろん、これはすべて画像のアルファ チャネルで機能します...

そのマスクを取得したら、2 つの画像を結合する必要があります (元の画像をマスクされた画像に重ねます)。

この例では、JHLabs フィルターを使用してぼかしを提供しています...

ここに画像の説明を入力

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;
    }
}
于 2013-02-01T22:49:59.720 に答える
1

これは私のバージョンです:

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;
}
于 2016-11-27T20:47:47.960 に答える