|
可以使用算法实现镜面等各种效果,但也可以简单的通过使用Swing提供的方法实现一些特殊效果。
Swing自带了12种Composite,合理利用还是挺不错的.
源图像:
镜面效果:
代码:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class ReflectedImage extends JPanel {
private BufferedImage img;
public ReflectedImage() {
img = loadImage("apple.png");
img = createReflectedImage(img);
setBackground(Color.BLACK);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.drawImage(img, 30, 30, null);
}
// 因为Swing的back-buffer是不透明的,所以要自己创建一个透明图片来处理反射
public static BufferedImage createReflectedImage(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage reflect = new BufferedImage(w, h * 2, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = reflect.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// 绘制原图像
g2.drawImage(img, 0, 0, null);
// 绘制镜面图像
g2.translate(0, h + 1);
g2.drawImage(img, 0, 0, w, (int) (h / 1.5), 0, h, w, 0, null);
// 绘制透明的渐变
g2.setPaint(new GradientPaint(0, 0, new Color(1.0f, 1.0f, 1.0f, 0.9f), 0, (int) (h / 2),
new Color(1.0f, 1.0f, 1.0f, 0.0f)));
// 关键就在DstIn,只使用源图像的透明度,目标图像不透明的地方继续不透明:
// Ar = Ad * As
// Cr = Cd * As
g2.setComposite(AlphaComposite.DstIn);
g2.fillRect(0, 0, w, h);
g2.dispose();
return reflect;
}
// 读取图片
public static BufferedImage loadImage(String path) {
try {
return ImageIO.read(new File(path));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void createGuiAndShow() {
JFrame frame = new JFrame("Reflected Image");
frame.getContentPane().add(new ReflectedImage());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 520);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createGuiAndShow();
}
});
}
}
创建BufferedImage的时候最好不要直接new,这样效率会相当的差.改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,流畅。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|