锁定老帖子 主题:利用Swing的Api实现镜面效果
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-10
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(); } }); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-01-10
最后修改:2011-01-10
呵呵,不错
有个建议,创建BufferedImage的时候最好不要直接new,这样效率会相当的差,我在做三号管家的时候,开始也是全部用的new BufferedImage,后来发现皮肤图片比较大的时候卡的一塌糊涂。 最后改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,瞬间流畅。 |
|
返回顶楼 | |
发表时间:2011-01-10
003 写道 呵呵,不错
有个建议,创建BufferedImage的时候最好不要直接new,这样效率会相当的差,我在做三号管家的时候,开始也是全部用的new BufferedImage,后来发现皮肤图片比较大的时候卡的一塌糊涂。 最后改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,瞬间流畅。 是的,compatible image是与硬件相关的,能够显示得更快,缺点是在不同的环境下表现得不一样。如果只是显示则用compatible image,如果是做效果处理最好是使用buffered image,因为buffered image是平台无关的。 |
|
返回顶楼 | |
发表时间:2011-01-10
jorneyR 写道 003 写道 呵呵,不错
有个建议,创建BufferedImage的时候最好不要直接new,这样效率会相当的差,我在做三号管家的时候,开始也是全部用的new BufferedImage,后来发现皮肤图片比较大的时候卡的一塌糊涂。 最后改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,瞬间流畅。 是的,compatible image是与硬件相关的,能够显示得更快,缺点是在不同的环境下表现得不一样。如果只是显示则用compatible image,如果是做效果处理最好是使用buffered image,因为buffered image是平台无关的。 呃,那如果仅仅是为了显示效果变好,不涉及移植什么的,是不是还是compatible image好些呢? |
|
返回顶楼 | |
发表时间:2011-01-10
bitray 写道 jorneyR 写道 003 写道 呵呵,不错
有个建议,创建BufferedImage的时候最好不要直接new,这样效率会相当的差,我在做三号管家的时候,开始也是全部用的new BufferedImage,后来发现皮肤图片比较大的时候卡的一塌糊涂。 最后改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,瞬间流畅。 是的,compatible image是与硬件相关的,能够显示得更快,缺点是在不同的环境下表现得不一样。如果只是显示则用compatible image,如果是做效果处理最好是使用buffered image,因为buffered image是平台无关的。 呃,那如果仅仅是为了显示效果变好,不涉及移植什么的,是不是还是compatible image好些呢? compatible image是根据硬件环境加快显示速度,而不是显示效果最好。 需要效果好的,使用buffered image 需要速度快的,使用compatible image(因为不同的显示器,系统等支持颜色的深度都不一样,如8bit, 24bit, 32bit等) 这个需要看你的软件的应用范围,根据环境来权衡。 |
|
返回顶楼 | |
发表时间:2011-01-11
jorneyR 写道 bitray 写道 jorneyR 写道 003 写道 呵呵,不错
有个建议,创建BufferedImage的时候最好不要直接new,这样效率会相当的差,我在做三号管家的时候,开始也是全部用的new BufferedImage,后来发现皮肤图片比较大的时候卡的一塌糊涂。 最后改用GraphicsConfiguration.createCompatibleImage来获取BufferedImage,瞬间流畅。 是的,compatible image是与硬件相关的,能够显示得更快,缺点是在不同的环境下表现得不一样。如果只是显示则用compatible image,如果是做效果处理最好是使用buffered image,因为buffered image是平台无关的。 呃,那如果仅仅是为了显示效果变好,不涉及移植什么的,是不是还是compatible image好些呢? compatible image是根据硬件环境加快显示速度,而不是显示效果最好。 需要效果好的,使用buffered image 需要速度快的,使用compatible image(因为不同的显示器,系统等支持颜色的深度都不一样,如8bit, 24bit, 32bit等) 这个需要看你的软件的应用范围,根据环境来权衡。 太感谢了。解开了我一个疑惑。thank you |
|
返回顶楼 | |
发表时间:2011-01-11
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1275) at com.test.ReflectedImage.loadImage(ReflectedImage.java:70) at com.test.ReflectedImage.<init>(ReflectedImage.java:22) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.test.ReflectedImage.createReflectedImage(ReflectedImage.java:39) at com.test.ReflectedImage.<init>(ReflectedImage.java:23) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 我报了这个错误时怎么回事啊 |
|
返回顶楼 | |
发表时间:2011-01-11
kxys422834 写道 javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1275) at com.test.ReflectedImage.loadImage(ReflectedImage.java:70) at com.test.ReflectedImage.<init>(ReflectedImage.java:22) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.test.ReflectedImage.createReflectedImage(ReflectedImage.java:39) at com.test.ReflectedImage.<init>(ReflectedImage.java:23) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 我报了这个错误时怎么回事啊 首先要把源图像下载下来保存为apple.png和这个Java的类放在同一个文件夹下,然后才能运行。 |
|
返回顶楼 | |
发表时间:2011-01-11
jorneyR 写道 kxys422834 写道 javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1275) at com.test.ReflectedImage.loadImage(ReflectedImage.java:70) at com.test.ReflectedImage.<init>(ReflectedImage.java:22) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.test.ReflectedImage.createReflectedImage(ReflectedImage.java:39) at com.test.ReflectedImage.<init>(ReflectedImage.java:23) at com.test.ReflectedImage.createGuiAndShow(ReflectedImage.java:80) at com.test.ReflectedImage.access$0(ReflectedImage.java:78) at com.test.ReflectedImage$1.run(ReflectedImage.java:93) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 我报了这个错误时怎么回事啊 首先要把源图像下载下来保存为apple.png和这个Java的类放在同一个文件夹下,然后才能运行。 如果是用MyEclipse运行的话,那这个apple.png就得放到工程目录下才行 |
|
返回顶楼 | |
发表时间:2011-01-11
onlylau 写道 jorneyR 写道 kxys422834 写道 我报了这个错误时怎么回事啊 首先要把源图像下载下来保存为apple.png和这个Java的类放在同一个文件夹下,然后才能运行。 如果是用MyEclipse运行的话,那这个apple.png就得放到工程目录下才行 嘿嘿,Eclipse,MyEclipse的工作目录和类加载目录,很让人迷惑。 |
|
返回顶楼 | |