将 JPanel 保存为图像

2024-01-11

我正在开发一个应用程序,允许用户在图层中加载图像。用户可以在另一层上绘制一些图片并仅保存用户绘制的图像。这是我的代码:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class LayerDemo extends JApplet {

    private JLayeredPane mainLayer;

    private JPanel layer1;

    private JPanel layer2;

    private JLabel label;

    private ImageIcon imgIcon;


    /**
     * Create the applet.
     */
    public LayerDemo() {    
    }

    public void init() {
        Dimension mainDemension = new Dimension(1024,768);
        setSize(mainDemension);

        mainLayer = new JLayeredPane();   
        layer1 = new JPanel();
        layer1.setOpaque(false);
        layer1.setBounds(0, 0, this.getWidth(), this.getHeight());
        imgIcon = new ImageIcon("bear.jpg");
        label = new JLabel(imgIcon);
        label.setBounds(0, 0, imgIcon.getIconWidth(), imgIcon.getIconHeight());
        layer1.add(label);

        layer2 = new PaintDemo(true);
        layer2.setOpaque(false);
        layer2.setBounds(0, 0, this.getWidth(), this.getHeight());

        mainLayer.add(layer1, 1);
        mainLayer.add(layer2, 2);
        this.setContentPane(mainLayer);
    }

    public void paint(Graphics g) {    
    }

}

这是用户绘制的类:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelListener;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class PaintDemo extends JPanel {
    /**
     * field explanation
     */
    private Point startPoint = new Point();

    private Point endPoint = new Point();

    private Graphics2D g2;

    private int minX;

    private int minY;

    private int maxX;

    private int maxY;

    private int height;

    private int width;


    /**
     * Create the panel.
     */

    public PaintDemo(boolean isDoubleBuffer) {

        addMouseWheelListener(new MouseWheelListener() {
            public void mouseWheelMoved(MouseWheelEvent e) {
            }
        });
        this.setDoubleBuffered(isDoubleBuffer);
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                endPoint = e.getPoint();
                Graphics g = PaintDemo.this.getGraphics();
                paintComponent(g);
                minX = minX < endPoint.x ? minX : endPoint.x;
                minY = minY < endPoint.y ? minY : endPoint.y;
                maxX = maxX > endPoint.x ? maxX : endPoint.x;
                maxY = maxY > endPoint.y ? maxY : endPoint.y;
                startPoint = endPoint;
            }
        });
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                startPoint = e.getPoint();
                minX = startPoint.x;
                minY = startPoint.y;
                maxX = startPoint.x;
                maxY = startPoint.y;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                endPoint = e.getPoint();
                Graphics g = PaintDemo.this.getGraphics();
                paintComponent(g);
                minX = minX < endPoint.x ? minX : endPoint.x;
                minY = minY < endPoint.y ? minY : endPoint.y;
                maxX = maxX > endPoint.x ? maxX : endPoint.x;
                maxY = maxY > endPoint.y ? maxY : endPoint.y;
                minX = minX > 0 ? minX : 0;
                minY = minY > 0 ? minY : 0;
                maxX = maxX < 1024 ? maxX : 1024;
                maxY = maxY < 768 ? maxY : 768;
                width = maxX - minX;
                height = maxY - minY;
                saveImage();     
                startPoint = new Point();
                endPoint = new Point();

            }
        });
    }

    /**
     * Paint method
     * 
     * {@inheritDoc}
     */
    @Override
    public void paintComponent(Graphics g) {
        g2 = (Graphics2D)g;
        g2.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setFont(new Font("Serif", Font.BOLD, 18));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.red);
        g2.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
    }

    public void saveImage() {
        BufferedImage bi = new BufferedImage(PaintDemo.this.getWidth(), PaintDemo.this.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        paintComponent(g2);
        g2.dispose();
        try
        {
            ImageIO.write(bi, "jpg", new File("clip.jpg"));
        }
        catch(IOException ioe)
        {
            System.out.println("Clip write help: " + ioe.getMessage());
        }
    }
}

保存图像时,它只是空白图像。请帮助我。非常感谢。 P/S:我已经按照你的想法编辑了我的代码,但它不起作用。结果是没有图像背景,仍然保存空白图像。 :(


自定义绘制是通过重写面板的paintComponent()方法来完成的。然后使用 Graphics 对象进行绘画。

你不应该有一个空的paint()方法。

drawline() 方法不应使用 getGraphics() 方法。相反,应该将该代码移至 PaintComponent() 方法,然后使用传递给该方法的 Graphics 对象。

另外,您不应该重写小程序的 Paint() 方法。由于您的代码按实际大小绘制图像,因此您应该仅使用 JLabel 通过创建 ImageIcon 来显示图像。然后将标签添加到分层窗格以用作背景图像。

Edit:

为什么仍然有空的paint()方法?摆脱它,无需重写 Paint() 方法。

当我运行代码时,我收到一个安全异常,因为小程序无法写入文件,所以我无法测试这部分代码。但如果你有兴趣我用屏幕图像 http://tips4java.wordpress.com/2008/10/13/screen-image/创建组件的图像。

然而,你的主要问题是绘画代码是错误的。是的,您会看到绘制的线条,但它们不是永久性的。当您想要进行永久绘画时,切勿使用组件的 getGraphics() 方法。尝试画一些线,然后最小化小程序,然后恢复小程序,您就会明白我的意思。

解决方案是在 BufferedImage 上进行绘图。请参阅DrawOnImage示例来自定制绘画方法 http://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 JPanel 保存为图像 的相关文章

  • Java泛型类型要么扩展要么是父类

    我正在寻找一些如下所示的代码 public class Parent
  • Java 区域设置区分大小写

    我有以下代码来显示当前区域设置 System out println Locale getDefault System out println new Locale en US 上面给出的输出如下 en US en us 如何构造一个 Lo
  • log4j2 SMTP Appender:如何包含另一个级别的先前消息?

    我正在使用 log4j2 beta9 并且有以下配置 其中一部分
  • 如何通过双击图标来执行JAVA程序?

    我写了一个java程序 现在我想在没有 IDE Eclipse 等的情况下打开我的控制台 java 应用程序 只需双击桌面上的可执行版本即可 我已将 java 项目导出为 Runnable JAR 文件 但无法打开 当我尝试使用cmd打开应
  • 原型 Bean 未按预期自动装配

    测试控制器 java RestController public class TestController Autowired private TestClass testClass RequestMapping value test me
  • Java setLocation() 事故

    我正处于创建一个程序来操作员工 客户系统的开始阶段 现在我刚刚创建了登录 GUI 但我遇到了一些问题 setLocation 方法 我将其设置为 250 250 但这使我的 GUI 高度变得非常疯狂 如果有人能够解决这个问题 我的代码如下
  • 在同一个容器但不同的耳朵中使用本地EJB

    我正在尝试在同一个 Glassfish 但不同的耳朵中使用本地 EJB 但是Glassfish找不到本地EJB或者无法消费 我读到了这个 根据 JavaEE 教程 Local bean 的客户端 必须在与其访问的企业 bean 相同的 JV
  • 无法安装 JDK 9,因为“另一个 Java 安装正在进行中”

    我已经在 Windows 10 x64 上使用 JDK 9 一段时间了 但是当我去安装最新的早期版本 b174 时 我首先卸载了以前的版本 像往常一样 然后运行新的安装程序 它失败并显示一个消息框 显示 另一个 Java 安装正在进行中 您
  • Java DocumentBuilder - XML 文件中的缩进错误

    我尝试使用 DocumentBuilder 用 Ja va 编写一个简单的 XML 文件 我期望 XML 文件如下所示
  • 在 Tomcat 中触发内部 ServletRequest

    我正在使用 Quartz 来安排 Web 应用程序的后台任务 其中一些任务只是针对同一 Web 应用程序发出请求 我想避免依赖于任何类型的网络设置 例如 如果从数据中心内发出带有我自己域名的请求 则可能无法正确路由 是否有一个 Java A
  • 错误:找不到符号 ArrayList

    我正在尝试创建某种列表来存储数组 表 中的值 我在这里使用数组列表 但我应该使用列表吗 但是 每次我尝试编译时 它都会引发以下错误 找不到标志 符号 ArrayList类 位置 玩家类 TablePlayer 代码如下 public cla
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • 我可以使用本机系统窗口作为父窗口使 JDialog 成为模式吗?

    我有一个 JDialog 窗口 我需要使其成为模态窗口 但父窗口不是 Java 窗口 而是本机 Windows 操作系统窗口 是否可以 不 你不能 您甚至无法不仅引用本机窗口 甚至无法引用运行在其他 JVM 中的 java 应用程序创建的窗
  • 使用 Swift 在 iOS 和 Android 之间共享核心代码

    我想要的是 使用 Swift 在 Android 和 iOS 之间共享非 UI 代码 问题 Android 具有 NDK 支持 允许您使用 Java 本机接口 JNI 运行 C 和 C 代码 不是 Objective C 我是一名Java程
  • JavaFX颜色选择器的语言

    有没有办法改变语言ColorPicker的文本 例如 自定义颜色 当前颜色 新颜色 色相 饱和度 亮度 不透明度 保存 使用 取消 编辑 以下答案适合那些需要更多内容的人exotic语言 如果您使用其中之一 de es fr it ja k
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • 将菜单添加到空活动

    我在 Android Studio 中制作了一个 Android 应用程序 并想在其上创建一个选项菜单 我将其创建为一个空活动 现在意识到我最好创建一个空白活动来获取选项菜单 无论如何 是否可以在空活动中创建选项菜单 如果有人能给我指出一个
  • 寻找基于循环固定大小数组的双端队列

    我正在寻找一个Deque其具有以下特点 它有固定的大小 如果我在头 尾添加元素 则另一端的元素会丢失 它是基于数组的 所以我可以在恒定时间内访问随机元素 我可以在前面或末尾添加元素 双端队列 我检查了Deque的实施JCF但我没有找到任何合
  • Image.Save 异常“GDI+ 中发生一般错误。”保存到 MemoryStream 时

    我有一个服务器客户端应用程序 我想从服务器获取屏幕截图 但在线bitmap Save ms System Drawing Imaging ImageFormat Png 我得到这个例外 A generic error occurred in
  • Java中不同格式的字符串解析为日期

    我想转换String to Date以不同的格式 例如 我从用户那里得到 String fromDate 19 05 2009 i e dd MM yyyy format 我想转换这个fromDate作为日期对象 yyyy MM dd fo

随机推荐

  • 在运行时更改 spring-cloud-stream 实例索引/计数

    在 spring cloud stream 中 有没有一种方法可以在不重新启动应用程序的情况下更改应用程序的实例计数和实例索引 另外 是否有任何推荐的方法来自动填充这些值 在微服务世界中 这似乎非常困难 因为服务一直在启动和停止 在 spr
  • 在 python 中调试 argparse

    我可以知道调试 argpars 函数的最佳实践是什么 假设我有一个 py 文件 test file py 其中包含以下几行 Script start import argparse import os parser argparse Arg
  • Vue.js 单击时切换类

    如何在 vue js 中切换类 我有以下内容 th class initial span class wkday M span th new Vue el my container data methods myFilter functio
  • Grails:获取控制器内资产的本地存储路径

    我需要提取资产文件夹物理路径 以便从控制器写入文件 有什么简单的方法可以从控制器实现文件持久性吗 完整示例 class ExampleService def assetResourceLocator def someMethod Resou
  • UISwitch,Mac 上有类似的东西吗?

    我相信你们大多数人都熟悉UISwitch on iOS 他们是否有任何现有项目试图实施类似的东西UISwitch适用于 macOS 和 AppKit 如果没有 从哪里开始制作呢 我经常看到它们并且能想到很多用途 我认为你应该使用NSChec
  • 如何在颤振中显示带有顶部和底部渐变阴影的图像?

    我正在研究颤振以显示具有顶部和底部渐变叠加的图像 图像顶部和底部的某些部分应显示阴影 就像被其他颜色 如灰色 覆盖一样 请找到我画的附图供参考 我已将 Container 与 CachedNetworkImage 一起使用 并尝试使用 Bo
  • 如何在摇动设备时刷新应用程序?

    我需要添加一个摇动功能来刷新我的 Android 应用程序 我找到的所有文档都涉及实施SensorListener 但 Eclipse 告诉我它已被弃用并建议SensorEventListener 任何人都可以指导我如何创建这个shake
  • 如何检查函数/方法采用哪些参数? [复制]

    这个问题在这里已经有答案了 为了保持我用 Python 构建的几个模块的一致性 我想做一些自动代码检查 为此 我想检查模块的函数以及函数所采用的参数 我可以使用 hasattr 来检查模块是否确实包含预期的功能 到目前为止 一切都很好 我现
  • 向量在着色器语言中如何相乘?

    Such as gl FragColor v1 v2 我真的不明白它是如何相乘的 似乎参考文献给出了向量乘法矩阵的解释 ps 类型v1 and v2都是vec4 The 操作员工作组件方面 http en wikibooks org wik
  • 使用 GET 请求发送 POST 数据是否有效?

    例如 使用 Curl 我可以在 GET 请求中 发布 数据 发送实体主体 这是有效的做法吗 我的意思是 RFC 规范没有禁止吗 有人有充分理由使用它吗 See RFC2616 超文本传输 协议 HTTP 1 1 http www faqs
  • AppDomains 和 GC 堆

    是否存在单个 GC 堆进程宽分区 使得每个应用程序域都可以访问特定分区 或者每个应用程序域都有单独的GC堆 我确定其他堆 例如 HF 堆 LF 堆 存根堆 句柄表等等 所有这些堆都是为每个应用程序域单独分配的吗 GC堆也单独分配吗 这可能是
  • .dSYM 文件是如何创建的?

    我正在与另一位开发人员一起开发一个应用程序 他们刚刚向在他们的计算机上构建的应用程序商店提交了一个版本 为了在我的机器上进行构建 属于同一个 git 提交 我必须更改我们在 XCode 项目中使用的库之一的路径 我对 XCode 项目文件所
  • 比较日期范围

    在 MySQL 中 如果我有一个日期范围列表 范围开始和范围结束 例如 10 06 1983 to 14 06 1983 15 07 1983 to 16 07 1983 18 07 1983 to 18 07 1983 我想检查另一个日期
  • 最简单的内联方法左填充字符串[重复]

    这个问题在这里已经有答案了 可能的重复 是否有 JavaScript 函数可以填充字符串以达到确定的长度 https stackoverflow com questions 2686855 is there a javascript fun
  • 寻找一个好的 C++ 库来解析 AMF3 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用阿姆达尔定律计算性能增益

    我对阿姆达尔定律来确定性能增益和串行应用程序部分感到困惑 但未能弄清楚这一点 已知的是以下内容 S N Speedup factor for N CPU s N Number of CPU s f The part of the progr
  • 使用 REST 服务上传文件

    我使用以下 REST 服务 来自本教程 https javatutorial net java file upload rest service 使用 jersey 多部分实现将文件从不同数量的客户端上传到我的 GlassFish 服务器
  • 使用 UIAppearance 设置 UITableView 的背景颜色

    我正在尝试普遍更改表格视图的背景颜色 它是 UINavigationController 和 TabBarController 应用程序的组合 我尝试将以下内容放入 AppDelegate applicationDidFinishLaunc
  • 是否有任何 EJB 迁移工具可用于将 EJB 2.1 迁移到 EJB 3.x

    最好的方法可能是手动完成 但在大型项目中 您需要一些工具来帮助您 正是这个想法促使我寻找一种工具 是否有任何 EJB 迁移工具可用于将 EJB 2 0 迁移到 3 x 它只开发了很短一段时间 但在一段时间内我们确实有一个 eclipse 插
  • 将 JPanel 保存为图像

    我正在开发一个应用程序 允许用户在图层中加载图像 用户可以在另一层上绘制一些图片并仅保存用户绘制的图像 这是我的代码 import java awt Dimension import java awt Graphics import jav