java设置方块阴影,Java:在图像上创建阴影效果

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. Unfortunately I always have the same problem: the shadow effect repaints the entire image in gray (i.e. the shadow color) - hence the original image is not visible anymore.

Example of code I tested (based on the JIDE freely available library):

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"));

No need to says that I tested this with multiple source files (out2.png).

I'm clueless: any hint/help would be highly appreciated.

解决方案

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...

yvzTV.png

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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值