锁定老帖子 主题:Swing 实现截图小软件 (四)
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-25
最后修改:2011-02-28
接上一节, 我们的截图小软件,功能基本完成,就剩下最后的 水印 功能了。
下面就来实现水印功能。
所谓图像的水印:就是将要做为水印的文字或图像,覆盖到目标图像(需要被加水印的图像)的指定位置。
根据上面解释,可以采用的方案为: 1. 取得 图标图像 的 Image 对象 和 水印图像 的 Image 对象 2. 创建一个缓冲图形对象(BufferedImage) bi 3. 将目标图像画到 bi 中 4. 将水印文字或图像 画到 bi 的指定位置 5. 返回 bi ,bi 即为 加上水印后的图像
代码: /** * 给图片添加文字水印 * @param targetImage 需要加上水印的图片 * @param text 用做水印的文字 * @param font 水印文字的字体 * @param color 水印文字的颜色 * @param x * @param y * @return 加上水印后的BufferedImage对象 */ public static BufferedImage addImageWaterMark(Image targetImage, String text, Font font, Color color, int x, int y) { int width = targetImage.getWidth(null); int height = targetImage.getHeight(null); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = bi.getGraphics(); g.drawImage(targetImage, 0, 0, null); g.setFont(font); g.setColor(color); g.drawString(text, x, y); g.dispose(); return bi; } /** * 给图片添加图片水印 * @param markImage 用做水印的图片 * @param targetImage 需要加上水印的图片 * @param x * @param y * @return 加上水印后的BufferedImage对象 */ public static BufferedImage addImageWaterMark(Image targetImage, Image markImage, int x, int y) { int wideth = targetImage.getWidth(null); int height = targetImage.getHeight(null); BufferedImage bi = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB); Graphics g = bi.createGraphics(); g.drawImage(targetImage, 0, 0, null); g.drawImage(markImage, x, y, null); g.dispose(); return bi; }
有了水印方法后,只需在 主程序中加入两个 按钮 调用即可。 部分代码: textWaterMarkButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(imageLabel.getIcon() == null) { JOptionPane.showMessageDialog(SnapShoot.this, "没有图片信息,请先截图", "提示", JOptionPane.INFORMATION_MESSAGE); return; } //取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //添加文字水印 bi = GraphicsUtils.addImageWaterMark(img, "文字水印", new Font("黑体", Font.BOLD, 30), Color.RED, 50, 50); //将加好水印的图像,设置到imageLabel imageLabel.setIcon(new ImageIcon(bi)); } }); imageWaterMarkButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(imageLabel.getIcon() == null) { JOptionPane.showMessageDialog(SnapShoot.this, "没有图片信息,请先截图", "提示", JOptionPane.INFORMATION_MESSAGE); return; } try { //取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //取得水印图像 Image markImage = ImageIO.read(SnapShoot.class.getResourceAsStream("waterMark.gif")); //添加图像水印 bi = GraphicsUtils.addImageWaterMark(img, markImage, 100, 100); //将加好水印的图像,设置到imageLabel imageLabel.setIcon(new ImageIcon(bi)); } catch (IOException e1) { e1.printStackTrace(); } } });
这样图像的水印功能就做好了。如图: 完成代码见附件:SnapShoot1.jar
水印功能虽然实现了,但水印的文字和图像,位置都固定了,不能改。那么,接下来,为了水印文字和图像的灵活性,增加一个水印的参数配置对话框。
第一步:增加一个JavaBean 作为对话框的返回值 /** * 用于水印参数的 JavaBean * @author pengranxiang */ public class WaterMarkBean { private Image image; //水印图像 private String text; //水印文字 private Font font; //文字字体 private Color color; //文字颜色 private int x,y; //水印位置 //省略 get/set 方法 }
第二步:做一个对话框,如图: 图片选择,字体,颜色 需要三个对话框。 文件选择对话框:JFileChooser,颜色选择对话框:JColorChooser, 这两个Sun有提供。 但是 字体选择对话框 就没有了。 以前在网上找到过一个自制的字体对话框, 忘了作者了。。。。
就直接拿来用吧。
关于缩略图,可以使用 // 关于 该方法的解释 请查看API bi.getScaledInstance(30, 30, Image.SCALE_FAST)
增加水印参数设置后的最终效果图:
到此,我们的截图小软件就告一段落了。 小软件完整代码见附件 SnapShoot.jar
附:
1. 增加截图时隐藏窗口的效果
需要两步完成:
a. 将 ScreenWindow 设置为 :总显示在最前面 setAlwaysOnTop(true); snapButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { //隐藏主窗口 SnapShoot.this.setVisible(false); //防止ScreenWindow生成太快,在主窗口未隐藏前就截图 Thread.sleep(10); //开启模拟屏幕,将显示截图的目标组件传入 new ScreenWindow(imageLabel); //显示主窗口,因为 Screen 显示在最前面,所以在 ScreenWindow 退出之前 看不到主窗口 SnapShoot.this.setVisible(true); } catch (AWTException e1) { e1.printStackTrace(); } catch (InterruptedException e1) { e1.printStackTrace(); } } }); 2. 提供将剪切的图片保存到 系统剪贴板 的功能
将图片写入系统剪贴板可以使用如下方法: /** * 将指定图片写入系统剪贴板 * @param image */ public static void setClipboardImage(final Image image) { Transferable trans = new Transferable() { public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.imageFlavor }; } public boolean isDataFlavorSupported(DataFlavor flavor) { return DataFlavor.imageFlavor.equals(flavor); } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (isDataFlavorSupported(flavor)) return image; throw new UnsupportedFlavorException(flavor); } }; Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null); } 附件:SnapShoot.jar 已经重新上传, 增加了上面的两个附加功能。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-02-26
这个很不错!
|
|
返回顶楼 | |
发表时间:2011-02-26
不错。
可以做一个远程控制的Java Swing应用。 |
|
返回顶楼 | |
发表时间:2011-02-26
和HyperSnap效果差不多了啊。
另外,在截图时应该将软件窗口隐藏掉。 |
|
返回顶楼 | |
发表时间:2011-02-27
可以截图时直接复制到剪切板中么?
|
|
返回顶楼 | |
发表时间:2011-02-28
NeighborWolf 写道 和HyperSnap效果差不多了啊。
另外,在截图时应该将软件窗口隐藏掉。 多谢提醒, 已经增加这个效果了。 |
|
返回顶楼 | |
发表时间:2011-02-28
sdtm1016 写道 可以截图时直接复制到剪切板中么? 已经增加 保存到剪贴板的 功能 |
|
返回顶楼 | |
发表时间:2011-02-28
非常好,
1.另外可不可以在截图时,直接就保存在剪切板中,不用点那个按钮(对于做测试的人,这会少了很多工作量,尤其是要贴几百个图时到excel时) 2.绑定快捷链,替换掉系统那个,或者自定义个 这二个弄了,就完美了 |
|
返回顶楼 | |
发表时间:2011-02-28
厉害!继续完善!
截图时隐藏主界面的我试了怎么没有? 另外内存上还是蛮大感觉。 |
|
返回顶楼 | |
发表时间:2011-03-01
sdtm1016 写道 非常好, 1.另外可不可以在截图时,直接就保存在剪切板中,不用点那个按钮(对于做测试的人,这会少了很多工作量,尤其是要贴几百个图时到excel时) 2.绑定快捷链,替换掉系统那个,或者自定义个 这二个弄了,就完美了 这两个功能已经加上了。 看这里 http://pengranxiang.iteye.com/admin/blogs/935433 |
|
返回顶楼 | |