2014-10-28 4 views
0

Что я хочу делать в своем приложении:Выбор, копирование и вставка изображений

1 - Выберите область изображения и получите координаты. Этот код ниже должен сделать это:

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import javax.swing.*; 

public class ScreenCaptureRectangle { 

Rectangle captureRect; 

ScreenCaptureRectangle(final BufferedImage screen) { 
    final BufferedImage screenCopy = new BufferedImage(
      screen.getWidth(), 
      screen.getHeight(), 
      screen.getType()); 
    final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy)); 
    JScrollPane screenScroll = new JScrollPane(screenLabel); 

    screenScroll.setPreferredSize(new Dimension(
      (int)(screen.getWidth()/3), 
      (int)(screen.getHeight()/3))); 

    JPanel panel = new JPanel(new BorderLayout()); 
    panel.add(screenScroll, BorderLayout.CENTER); 

    final JLabel selectionLabel = new JLabel(
      "Drag a rectangle in the screen shot!"); 
    panel.add(selectionLabel, BorderLayout.SOUTH); 

    repaint(screen, screenCopy); 
    screenLabel.repaint(); 

    screenLabel.addMouseMotionListener(new MouseMotionAdapter() { 

     Point start = new Point(); 

     @Override 
     public void mouseMoved(MouseEvent me) { 
      start = me.getPoint(); 
      repaint(screen, screenCopy); 
      selectionLabel.setText("Start Point: " + start); 
      screenLabel.repaint(); 
     } 

     @Override 
     public void mouseDragged(MouseEvent me) { 
      Point end = me.getPoint(); 
      captureRect = new Rectangle(start, 
        new Dimension(end.x-start.x, end.y-start.y)); 
      repaint(screen, screenCopy); 
      screenLabel.repaint(); 
      selectionLabel.setText("Rectangle: " + captureRect); 
     } 
    }); 

    JOptionPane.showMessageDialog(null, panel); 

    System.out.println("Rectangle of interest: " + captureRect); 
} 

public void repaint(BufferedImage orig, BufferedImage copy) { 
    Graphics2D g = copy.createGraphics(); 
    g.drawImage(orig,0,0, null); 
    if (captureRect!=null) { 
     g.setColor(Color.RED); 
     g.draw(captureRect); 
     g.setColor(new Color(255,255,255,150)); 
     g.fill(captureRect); 
    } 
    g.dispose(); 
} 

public static void main(String[] args) throws Exception { 
    Robot robot = new Robot(); 
    final Dimension screenSize = Toolkit.getDefaultToolkit(). 
      getScreenSize(); 
    final BufferedImage screen = robot.createScreenCapture(
      new Rectangle(screenSize)); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new ScreenCaptureRectangle(screen); 
     } 
    }); 
} 
} 

2 - получить координаты и использовать их по методу getSubimage.

double w = captureRect.getWidth(); 
double h = captureRect.getHeight(); 
double x = captureRect.getX(); 
double y = captureRect.getY(); 

int W = (int) w; 
int H = (int) h; 
int X = (int) x; 
int Y = (int) y; 

BufferedImage selectImg = screen.getSubimage(x, y, w, h); 

3 - этот код создает новый файл изображения и копирует выбранные изображения.

BufferedImage img = new BufferedImage (5000, 5000, BufferedImage.TYPE_INT_RGB); 
img.createGraphics().drawImage(selectImg, 0, 0, null); 
File final_image = new File("C:/Final.jpg"); 
ImageIO.write(img, "jpeg", final_image); 

Идея приложения является:
- Выберите область изображения.
- Скопируйте это изображение и вставьте его в другой файл. (когда я нажал любую кнопку)
- Программа продолжит работу, пока я не нажму другую кнопку.
- Каждое изображение, которое я копирую программу, вставляет его рядом с последним.

Я думаю, что я близок к решению. Может ли кто-нибудь помочь мне «соединить детали»?

+0

* «когда я нажал любую нижнюю» * - Вы имеете в виду «кнопку»? – MadProgrammer

+0

* «Каждое изображение, которое я копирую программу, вставляет его рядом с последним» * - Я предполагаю, что это означает на экране, или вы имеете в виду, что файлы должны быть названы последовательно? – MadProgrammer

+0

Да, вы правы. Он работает на одном экране. Мне нужен только один файл изображения. Большое спасибо. Я пытаюсь понять, что вы сделали, но это прекрасно –

ответ

0

Вам нужно больше слушателей для нажатия и отпускания кнопки. Некоторые строки в mouseMoved также лучше размещены в mousePressed.
Вы хотите обновить captureRect, когда вы отпустите мышь (в методе mouseReleased).
Тогда вы просто напишите его в файл. Вы можете настроить другие вещи в соответствии с вашими потребностями.

И для наглядности, возможно, лучше добавить кнопку сохранения в свой интерфейс.

public class ScreenCaptureRectangle { 

    Rectangle captureRect; 
    Point start = new Point(); 
    SimpleDateFormat sdf; 

    ScreenCaptureRectangle(final BufferedImage screen) { 
     sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); 
     final BufferedImage screenCopy = new BufferedImage(
       screen.getWidth(), 
       screen.getHeight(), 
       screen.getType()); 
     final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy)); 
     JScrollPane screenScroll = new JScrollPane(screenLabel); 

     screenScroll.setPreferredSize(new Dimension(
       (int) (screen.getWidth()/3), 
       (int) (screen.getHeight()/3))); 

     JPanel panel = new JPanel(new BorderLayout()); 
     panel.add(screenScroll, BorderLayout.CENTER); 
     JButton btnSave = new JButton("SAVE"); 
     btnSave.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       double w = captureRect.getWidth(); 
       double h = captureRect.getHeight(); 
       double x = captureRect.getX(); 
       double y = captureRect.getY(); 

       int W = (int) w; 
       int H = (int) h; 
       int X = (int) x; 
       int Y = (int) y; 

       BufferedImage selectImg = screen.getSubimage(X, Y, W, H); 
       try { 
        String fName = generateFileName(); 
        if (fName != null) { 
         File f = new File(fName); 
         if (f.createNewFile()) { 
          ImageIO.write(selectImg, "jpg", f); 
         } 
        } 
       } catch (IOException ex) { 
        Logger.getLogger(ScreenCaptureRectangle.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     }); 
     panel.add(btnSave, BorderLayout.AFTER_LAST_LINE); 

     final JLabel selectionLabel = new JLabel(
       "Drag a rectangle in the screen shot!"); 
     panel.add(selectionLabel, BorderLayout.SOUTH); 

     repaint(screen, screenCopy); 
     screenLabel.repaint(); 

     screenLabel.addMouseMotionListener(new MouseMotionAdapter() { 

      @Override 
      public void mouseDragged(MouseEvent me) { 
       Point end = me.getPoint(); 
       captureRect = new Rectangle(start, 
         new Dimension(end.x - start.x, end.y - start.y)); 
       repaint(screen, screenCopy); 
       screenLabel.repaint(); 
       selectionLabel.setText("Rectangle: " + captureRect); 
      } 

     }); 

     screenLabel.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mousePressed(MouseEvent me) { 
       start = me.getPoint(); 
       repaint(screen, screenCopy); 
       selectionLabel.setText("Start Point: " + start); 
       screenLabel.repaint(); 
      } 

      @Override 
      public void mouseReleased(MouseEvent me) { 
       int endX = me.getX(); 
       int endY = me.getY(); 
       if (endX > start.x && endY > start.y) { 
        captureRect = new Rectangle(start.x, start.y, endX-start.x, endY-start.y); 
        System.out.println("Rectangle of interest: " + captureRect); 
       } 
      } 

     }); 

     JOptionPane.showMessageDialog(null, panel); 
    } 

    private String generateFileName() { 
     return new StringBuilder("screencrop_").append(sdf.format(new Date())).append(".jpg").toString(); 
    } 

    public void repaint(BufferedImage orig, BufferedImage copy) { 
     Graphics2D g = copy.createGraphics(); 
     g.drawImage(orig, 0, 0, null); 
     if (captureRect != null) { 
      g.setColor(Color.RED); 
      g.draw(captureRect); 
      g.setColor(new Color(255, 255, 255, 150)); 
      g.fill(captureRect); 
     } 
     g.dispose(); 
    } 

    public static void main(String[] args) throws Exception { 
     Robot robot = new Robot(); 
     final Dimension screenSize = Toolkit.getDefaultToolkit(). 
       getScreenSize(); 
     final BufferedImage screen = robot.createScreenCapture(
       new Rectangle(screenSize)); 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new ScreenCaptureRectangle(screen); 
      } 
     }); 
    } 
} 
+0

Спасибо, Йоханес. Это действительно хорошо. Извините за мой плохой английский. я попытался сказать: поместите всю выделенную область на одно и то же изображение файла. один рядом с другим. –

+0

Мое предложение: сделайте 'Список'' Прямоугольников' и ​​добавьте кнопку 'Capture'. Каждый раз, когда вы нажимаете 'Capture', вы должны добавить новый« Прямоугольник »выбора в« Список ». И когда вы нажимаете кнопку «Сохранить», вы должны перебирать эти прямоугольники и получать общий размер (это будет зависеть от того, как вы хотите их комбинировать), и нарисовать каждый субимаж в одном «BufferedImage», как вы хотите. Когда вы столкнетесь с большим количеством проблем, когда попробуете это, пожалуйста, спросите еще раз позже (в новом посте лучше, я думаю). Удачи! –

+0

Привет, Yohanes. Я сделал то, что вы сказали, но список имеет ограниченную длину. Поэтому я нашел этот код: [код] ArrayList al = new ArrayList (); al.add (новый прямоугольник (x, y, w, h)); [/ code] Но он не работает. Вы можете мне помочь ? –

2

Начните с взглянуть на:

Вам необходимо взять концепции, которые у вас есть, и переработать их в единое практичное решение. То есть, обеспечьте функциональность между областями, которые вам нужны (выберите регион и сохраните файл), чтобы они работали вместе ...

В следующем примере показан снимок экрана, который позволяет вам выбрать область, нажмите кнопку «Сохранить» и файл будет сохранен. Пример проверяет, сколько файлов уже в текущем каталоге и увеличивает счетчик на 1, так что вы не перезапись существующих файлов ...

Select my world

import java.awt.AWTException; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileFilter; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ScreenImage { 

    public static void main(String[] args) { 
     new ScreenImage(); 
    } 

    public ScreenImage() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 
       try { 
        Robot robot = new Robot(); 
        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
        final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize)); 

        JFrame frame = new JFrame("Testing"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(new TestPane(screen)); 
        frame.setSize(400, 400); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (AWTException exp) { 
        exp.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage master; 

     public TestPane(BufferedImage image) { 
      this.master = image; 
      setLayout(new BorderLayout()); 
      final ImagePane imagePane = new ImagePane(image); 
      add(new JScrollPane(imagePane)); 

      JButton btnSave = new JButton("Save"); 
      add(btnSave, BorderLayout.SOUTH); 

      btnSave.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        try { 
         BufferedImage img = imagePane.getSubImage(); 
         master = append(master, img); 
         File save = new File("Capture.png"); 
         ImageIO.write(master, "png", save); 
         imagePane.clearSelection(); 
         JOptionPane.showMessageDialog(TestPane.this, save.getName() + " was saved", "Saved", JOptionPane.INFORMATION_MESSAGE); 
        } catch (IOException ex) { 
         ex.printStackTrace(); 
         JOptionPane.showMessageDialog(TestPane.this, "Failed to save capture", "Error", JOptionPane.ERROR_MESSAGE); 
        } 
       } 

       public BufferedImage append(BufferedImage master, BufferedImage sub) { 

        // Create a new image which can hold both background and the 
        // new image... 
        BufferedImage newImage = new BufferedImage(
            master.getWidth() + sub.getWidth(), 
            Math.max(master.getHeight(), sub.getHeight()), 
            BufferedImage.TYPE_INT_ARGB); 
        // Get new image's Graphics context 
        Graphics2D g2d = newImage.createGraphics(); 
        // Draw the old background 
        g2d.drawImage(master, 0, 0, null); 
        // Position and paint the new sub image... 
        int y = (newImage.getHeight() - sub.getHeight())/2; 
        g2d.drawImage(sub, master.getWidth(), y, null); 
        g2d.dispose(); 

        return newImage; 

       } 

      }); 

     } 

    } 

    public class ImagePane extends JPanel { 

     private BufferedImage background; 
     private Rectangle selection; 

     public ImagePane(BufferedImage img) { 
      background = img; 
      MouseAdapter ma = new MouseAdapter() { 

       private Point clickPoint; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        clickPoint = e.getPoint(); 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        Point dragPoint = e.getPoint(); 

        int x = Math.min(clickPoint.x, dragPoint.x); 
        int y = Math.min(clickPoint.y, dragPoint.y); 
        int width = Math.abs(clickPoint.x - dragPoint.x); 
        int height = Math.abs(clickPoint.y - dragPoint.y); 

        selection = new Rectangle(x, y, width, height); 
        repaint(); 

       } 

      }; 

      addMouseListener(ma); 
      addMouseMotionListener(ma); 
     } 

     public void clearSelection() { 
      selection = null; 
      repaint(); 
     } 

     public BufferedImage getSubImage() { 

      BufferedImage img = null; 
      if (selection != null) { 

       img = background.getSubimage(selection.x, selection.y, selection.width, selection.height); 

      } 
      return img; 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(background.getWidth(), background.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int x = (getWidth() - background.getWidth())/2; 
      int y = (getHeight() - background.getHeight())/2; 
      g2d.drawImage(background, x, y, this); 
      if (selection != null) { 
       Color stroke = UIManager.getColor("List.selectionBackground"); 
       Color fill = new Color(stroke.getRed(), stroke.getGreen(), stroke.getBlue(), 128); 
       g2d.setColor(fill); 
       g2d.fill(selection); 
       g2d.setColor(stroke); 
       g2d.draw(selection); 
      } 
      g2d.dispose(); 
     } 

    } 

} 

Так, помимо оказания выбора в самая сложная часть будет генерировать результирующее изображение ...

В основном, это сделано путем создания нового BufferedImage и покраски старого изображения и нового, суб, изображения вместе.

public BufferedImage append(BufferedImage master, BufferedImage sub) { 

    // Create a new image which can hold both background and the 
    // new image... 
    BufferedImage newImage = new BufferedImage(
        master.getWidth() + sub.getWidth(), 
        Math.max(master.getHeight(), sub.getHeight()), 
        BufferedImage.TYPE_INT_ARGB); 
    // Get new image's Graphics context 
    Graphics2D g2d = newImage.createGraphics(); 
    // Draw the old background 
    g2d.drawImage(master, 0, 0, null); 
    // Position and paint the new sub image... 
    int y = (newImage.getHeight() - sub.getHeight())/2; 
    g2d.drawImage(sub, master.getWidth(), y, null); 
    g2d.dispose(); 

    return newImage; 

} 

Пример заменяет предыдущий (мастер) изображение с одной созданной здесь, так что это будет постоянно добавляя новые изображения к концу этого ...

+0

Еще раз спасибо. Я попытался изучить те темы, которые вы указали, но все они на английском, и их понять сложно. Для крупных пользователей вы указываете книгу [Java: как программировать - Deitel]? (есть версия на португальском языке) –

+0

В ближайшее время я попытаюсь обновить пример, чтобы скопировать изображение обратно на экран. Книга, которую вы не читаете, не помогает вам. Ни одна книга не расскажет вам всего. Но попробуйте и получите тот, который достаточно обновлен, поскольку API недавно прошел некоторые изменения;) – MadProgrammer

+0

haha ​​Вы правы. Я буду изучать больше программ. Чтобы прояснить идею: программа должна вставлять каждую выбранную область изображения в другой файл. Один рядом с другим. Идея состоит в том, чтобы конкатенировать изображения так же, как и со строками. (: –

Смежные вопросы