【问题标题】:Developing an image editor in java用java开发一个图像编辑器
【发布时间】:2013-02-01 00:47:45
【问题描述】:

我正在尝试用 Java 开发图像编辑器。我的图像编辑器的 Java 图像实现的一部分是加载图像并绘制一些形状,以及执行旋转、缩放等。

我正在使用 JLabel 加载图像,但有没有办法使用 JLabel 在图像上绘制和应用转换?我在网上找到的所有示例都使用了 JPanel。

【问题讨论】:

  • 您想将对象和矢量图结合起来吗?你试过什么?你看过什么?请更新您的问题,使其更具建设性。

标签: java image swing editor


【解决方案1】:

你真的需要看看Java2D turorial。您应该在Graphics2D 上绘制图像,并在Graphics2D 上旋转和缩放图像。

不要使用JLabel,因为

  • J-* 组件很重(尽管JLabel 很轻)。您可以在 JLabel 中添加图标,但通常它们用于稳定的情况,不会更改 经常和任意。在 J-* 组件上绘制会带来 改动太多了。

  • 如果添加大量组件,也会降低性能。 (每个组件都将自己绘制在一个单独的 Graphics 对象中,该对象属于 它和它的容器会将它们全部绘制出来,布局也很重要。)

  • 另一个缺点是有时很难甚至不可能 对一个组件或几个组件一起做一些操作。例如,如果要添加两张图片并将它们分组怎么办?你需要 2 个JLabels,1 个JPanel(也许)。那么如果你想在这两张图片之间画一条线,然后再分组呢?

以下是基本步骤:

  1. 覆盖组件的paintpaintComponent 方法;
  2. Graphics 实例转换为Graphics2D
  3. 设置Graphics2D的一些渲染属性;
  4. 设置Graphics2D的变换(旋转、缩放等);
  5. Graphics2D上绘制图像

使用了各种各样的类,例如Graphics2DAffineTransformRenderingHintsBufferedImageShape等,甚至更多的方法。我无法描述这里的一切。只需阅读 Java2D 教程。它为您提供 API 的概述,并告诉您如何执行这些操作。

【讨论】:

    【解决方案2】:

    我正在使用 JLabel 加载图像,但可以绘制和应用 使用 JLabel 对图像进行转换?

    不确定你的意思。

    但是您可以简单地获取JLabel 的图标(即显示的图像)对我们转换为BufferedImage 的图标执行需要执行的操作,然后通过setIcon(..) 重新应用该图标。

    这是一个简短的示例,希望对您有所帮助:

    JLabel 带有图标/BufferedImage 在旋转 -45 度之前:

    JLabel 获取图标后,通过setIcon(...) 旋转并重新应用:

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.event.ActionEvent;
    import java.awt.image.BufferedImage;
    import javax.swing.AbstractAction;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class Test {
    
        private static JLabel imageLabel;
        private static JFrame frame;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
                    JPanel panel = new JPanel();
    
                    imageLabel = new JLabel(new ImageIcon(createImage()));//set image of JLabel
    
                    panel.add(imageLabel);
    
                    frame.add(panel);
    
                    frame.pack();
                    frame.setVisible(true);
    
                    startImageChangeTimer();//creates a timer which will rotate image after 5 seconds
                }
    
                private void startImageChangeTimer() {
                    Timer timer = new Timer(5000, new AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent ae) {
                            //get JLabel Icon and convert to BufferedImage
                            BufferedImage img = getBufferedImageOfIcon(imageLabel.getIcon(), imageLabel.getWidth(), imageLabel.getHeight());
                            //rotate the image
                            img = createTransformedImage(img, -45);
                            //change the labels image
                            imageLabel.setIcon(new ImageIcon(img));
    
                            frame.pack();//resize frame accrodingly
                        }
                    });
                    timer.setRepeats(false);
                    timer.start();
                }
            });
        }
    
        public static BufferedImage createImage() {
            BufferedImage img = new BufferedImage(100, 50, BufferedImage.TRANSLUCENT);
            Graphics2D g2d = img.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
            g2d.setColor(Color.BLACK);
            g2d.setFont(new Font("Calibri", Font.BOLD, 20));
            FontMetrics fm = g2d.getFontMetrics();
            String text = "Hello world";
            int textWidth = fm.stringWidth(text);
            g2d.drawString(text, (img.getWidth() / 2) - textWidth / 2, img.getHeight() / 2);
            g2d.dispose();
            return img;
        }
    
        public static BufferedImage getBufferedImageOfIcon(Icon icon, int imgW, int imgH) {
            BufferedImage img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = (Graphics2D) img.getGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            icon.paintIcon(null, g2d, 0, 0);
            g2d.dispose();
            return img;
        }
    
        public static BufferedImage createTransformedImage(BufferedImage image, double angle) {
            double sin = Math.abs(Math.sin(angle));
            double cos = Math.abs(Math.cos(angle));
            int originalWidth = image.getWidth();
            int originalHeight = image.getHeight();
            int newWidth = (int) Math.floor(originalWidth * cos + originalHeight * sin);
            int newHeight = (int) Math.floor(originalHeight * cos + originalWidth * sin);
            BufferedImage rotatedBI = new BufferedImage(newWidth, newHeight, BufferedImage.TRANSLUCENT);
            Graphics2D g2d = rotatedBI.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.translate((newWidth - originalWidth) / 2, (newHeight - originalHeight) / 2);
            g2d.rotate(angle, originalWidth / 2, originalHeight / 2);
            g2d.drawImage(image, 0, 0, null);
            g2d.dispose();
            return rotatedBI;
        }
    }
    

    更新:

    我确实倾向于同意@shuangwhywhy。通过paintComponent(Graphics g) 将图像绘制到JPanel,因此您可以简单地调整图像大小并将其设置为JPanel 图像(通过getter 和setter),然后调用repaint() 来显示更改。

    【讨论】:

      【解决方案3】:

      这是简单的图像编辑器

        /*Arpana*/
        CPanel displayPanel;
      
        JButton sharpenButton, blurringButton, edButton, resetButton;
      
        public ConvolveApp()
          super();
          Container container = getContentPane();
      
          displayPanel = new CPanel();
          container.add(displayPanel);
      
          JPanel panel = new JPanel();
          panel.setLayout(new GridLayout(2, 2));
          panel
              .setBorder(new TitledBorder(
                  "Click a Button to Perform the Associated Operation and Reset..."));
      
          sharpenButton = new JButton("Sharpen");
          sharpenButton.addActionListener(new ButtonListener());
          blurringButton = new JButton("Blur");
          blurringButton.addActionListener(new ButtonListener());
          edButton = new JButton("Edge Detect");
          edButton.addActionListener(new ButtonListener());
          resetButton = new JButton("Reset");
          resetButton.addActionListener(new ButtonListener());
      
          panel.add(sharpenButton);
          panel.add(blurringButton);
          panel.add(edButton);
          panel.add(resetButton);
      
          container.add(BorderLayout.SOUTH, panel);
      
          addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
      
          setSize(displayPanel.getWidth(), displayPanel.getHeight() + 10);
          setVisible(true); 
      
        public static void main(String arg[]) {
          new ConvolveApp();
      
      
        class ButtonListener implements ActionListener 
          public void actionPerformed(ActionEvent e) 
            JButton button = (JButton) e.getSource();
      
            if (button.equals(sharpenButton)) 
              displayPanel.sharpen();
              displayPanel.repaint();
             else if (button.equals(blurringButton)) 
              displayPanel.blur();
              displayPanel.repaint();
             else if (button.equals(edButton)) 
              displayPanel.edgeDetect();
              displayPanel.repaint();
            else if (button.equals(resetButton)) 
              displayPanel.reset();
              displayPanel.repaint();
      
      
      class CPanel extends JLabel 
        Image displayImage;
      
        BufferedImage biSrc;
      
        BufferedImage biDest; 
      
        BufferedImage bi; 
      
        Graphics2D big;
      
        CPanel()
          setBackground(Color.black);
          loadImage();
          setSize(displayImage.getWidth(this), displayImage.getWidth(this)); 
          createBufferedImages();
          bi = biSrc;
      
      
        public void loadImage() 
          displayImage = Toolkit.getDefaultToolkit().getImage("Arpana.jpg");
          MediaTracker mt = new MediaTracker(this);
          mt.addImage(displayImage, 1);
          try
            mt.waitForAll();
             if (displayImage.getWidth(this) == -1) 
            System.out.println("No jpg file");
            System.exit(0);
      
      
        public void createBufferedImages() 
          biSrc = new BufferedImage(displayImage.getWidth(this), displayImage
              .getHeight(this), BufferedImage.TYPE_INT_RGB);
      
          big = biSrc.createGraphics();
          big.drawImage(displayImage, 0, 0, this);
      
          biDest = new BufferedImage(displayImage.getWidth(this), displayImage
              .getHeight(this), BufferedImage.TYPE_INT_RGB);
      
      
        public void sharpen() 
          float data[] = { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f,
              -1.0f };
          Kernel kernel = new Kernel(3, 3, data);
          ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
              null);
          convolve.filter(biSrc, biDest);
          bi = biDest;
      
      
        public void blur() 
          float data[] = { 0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f,
              0.0625f, 0.125f, 0.0625f };
          Kernel kernel = new Kernel(3, 3, data);
          ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
              null);
          convolve.filter(biSrc, biDest);
          bi = biDest;
      
      
          public void edgeDetect() 
          float data[] = { 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
              -1.0f };
      
          Kernel kernel = new Kernel(3, 3, data);
          ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
              null);
          convolve.filter(biSrc, biDest);
      
      public void reset()
          big.setColor(Color.black);
          big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this));
          big.drawImage(displayImage, 0, 0, this);
          bi = biSrc;
      
      
        public void update(Graphics g) 
          g.clearRect(0, 0, getWidth(), getHeight());
          paintComponent(g);
      

      【讨论】:

        【解决方案4】:

        我只听说有人使用 JLabels 来完成此任务。我建议将 BufferedImage 显示为 JLabel 的背景。当用户对图像应用编辑时,编辑图像(如果您还没有用于处理图像的库,我强烈推荐imgscalr)并将其重新应用为 JLabel 的背景(如果它不自动更新)。

        【讨论】:

        【解决方案5】:
              /* Arpana*/   
             import java.awt.BorderLayout;
            import java.awt.Color;
            import java.awt.Container;
            import java.awt.Graphics;
            import java.awt.Graphics2D;
            import java.awt.GridLayout;
            import java.awt.Image;
            import java.awt.MediaTracker;
            import java.awt.Toolkit;
            import java.awt.event.ActionEvent;
            import java.awt.event.ActionListener;
            import java.awt.event.WindowAdapter;
            import java.awt.event.WindowEvent;
            import java.awt.image.BufferedImage;
            import java.awt.image.ConvolveOp;
            import java.awt.image.Kernel;
        
            import javax.swing.JButton;
            import javax.swing.JFrame;
            import javax.swing.JLabel;
            import javax.swing.JPanel;
            import javax.swing.border.TitledBorder;
        
            public class ConvolveApp extends JFrame {
              CPanel displayPanel;
        
              JButton sharpenButton, blurringButton, edButton, resetButton;
        
              public ConvolveApp() {
                super();
                Container container = getContentPane();
        
                displayPanel = new CPanel();
                container.add(displayPanel);
        
                JPanel panel = new JPanel();
                panel.setLayout(new GridLayout(2, 2));
                panel
                    .setBorder(new TitledBorder(
                        "Click a Button to Perform the Associated Operation and Reset..."));
        
                sharpenButton = new JButton("Sharpen");
                sharpenButton.addActionListener(new ButtonListener());
                blurringButton = new JButton("Blur");
                blurringButton.addActionListener(new ButtonListener());
                edButton = new JButton("Edge Detect");
                edButton.addActionListener(new ButtonListener());
                resetButton = new JButton("Reset");
                resetButton.addActionListener(new ButtonListener());
        
                panel.add(sharpenButton);
                panel.add(blurringButton);
                panel.add(edButton);
                panel.add(resetButton);
        
                container.add(BorderLayout.SOUTH, panel);
        
                addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {
                    System.exit(0);
                  }
                });
                setSize(displayPanel.getWidth(), displayPanel.getHeight() + 10);
                setVisible(true); 
              }
              public static void main(String arg[]) {
                new ConvolveApp();
              }
        
              class ButtonListener implements ActionListener {
                public void actionPerformed(ActionEvent e) {
                  JButton button = (JButton) e.getSource();
        
                  if (button.equals(sharpenButton)) {
                    displayPanel.sharpen();
                    displayPanel.repaint();
                  } else if (button.equals(blurringButton)) {
                    displayPanel.blur();
                    displayPanel.repaint();
                  } else if (button.equals(edButton)) {
                    displayPanel.edgeDetect();
                    displayPanel.repaint();
                  } else if (button.equals(resetButton)) {
                    displayPanel.reset();
                    displayPanel.repaint();
                  }
                }
              }
            }
        
            class CPanel extends JLabel {
              Image displayImage;
        
              BufferedImage biSrc;
        
              BufferedImage biDest; // Destination image is mandetory.
        
              BufferedImage bi; // Only an additional reference.
        
              Graphics2D big;
        
              CPanel() {
                setBackground(Color.black);
                loadImage();
                setSize(displayImage.getWidth(this), displayImage.getWidth(this)); 
                createBufferedImages();
                bi = biSrc;
              }
        
              public void loadImage() {
                displayImage = Toolkit.getDefaultToolkit().getImage("Arpana.jpg");
                MediaTracker mt = new MediaTracker(this);
                mt.addImage(displayImage, 1);
                try {
                  mt.waitForAll();
                } catch (Exception e) {
                  System.out.println("Exception while loading.");
                }
                if (displayImage.getWidth(this) == -1) {
                  System.out.println("No jpg file");
                  System.exit(0);
                }
              }
        
              public void createBufferedImages() {
                biSrc = new BufferedImage(displayImage.getWidth(this), displayImage
                    .getHeight(this), BufferedImage.TYPE_INT_RGB);
        
                big = biSrc.createGraphics();
                big.drawImage(displayImage, 0, 0, this);
        
                biDest = new BufferedImage(displayImage.getWidth(this), displayImage
                    .getHeight(this), BufferedImage.TYPE_INT_RGB);
              }
        
              public void sharpen() {
                float data[] = { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f,
                    -1.0f };
                Kernel kernel = new Kernel(3, 3, data);
                ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
                    null);
                convolve.filter(biSrc, biDest);
                bi = biDest;
              }
        
              public void blur() {
                float data[] = { 0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f,
                    0.0625f, 0.125f, 0.0625f };
                Kernel kernel = new Kernel(3, 3, data);
                ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
                    null);
                convolve.filter(biSrc, biDest);
                bi = biDest;
              }
        
                public void edgeDetect() {
                float data[] = { 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
                    -1.0f };
        
                Kernel kernel = new Kernel(3, 3, data);
                ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
                    null);
                convolve.filter(biSrc, biDest);
        
                bi = biDest;
              }
        
              public void reset() {
                big.setColor(Color.black);
                big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this));
                big.drawImage(displayImage, 0, 0, this);
                bi = biSrc;
              }
        
              public void update(Graphics g) {
                g.clearRect(0, 0, getWidth(), getHeight());
                paintComponent(g);
              }
        
              public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2D = (Graphics2D) g;
        
                g2D.drawImage(bi, 0, 0, this);
              }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-28
          • 2023-04-05
          相关资源
          最近更新 更多