2010-03-05 2 views
60

Я хочу обрезать изображение вручную с помощью мыши.
Предположим, что у изображения есть текст, и я хочу выбрать какой-то текст из изображения, затем для этой цели. Я хочу обрезать эту область с помощью мыши.Как обрезать изображение на Java?

+0

Несколько хороших идей ниже. См. Также http://java.sun.com/docs/books/tutorial/2d/ – trashgod

+0

Hussain: дайте один из этих подробных ответов чек – IcedDante

ответ

2

Вам нужно прочитать о Java Image API и API-интерфейсе, связанном с мышью, возможно, где-то под пакетом awt.event.

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

Затем оттуда вы попытаетесь реализовать интерфейс прослушивания мыши и другие связанные с ним интерфейсы. Может быть, вы будете привязываться по методе mouseDragged ...

Для mousedragged действия, вы получите координаты формы прямоугольника тормозных ...

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

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

+0

благодаря вашему предложению как я могу установить изображение на апплете с помощью панели для обрезки – Hussain

6

У этого вопроса недостаточно информации для ответа. Общее решение (в зависимости от вашей инфраструктуры графического интерфейса): добавьте обработчик события мыши, который будет захватывать клики и движения мыши. Это даст вам ваши (x, y) координаты. Затем используйте эти координаты, чтобы обрезать изображение.

+0

спасибо я постараюсь для него – Hussain

9

Это метод, который будет работать:

import javax.image.BufferedImage; // I think 
import java.awt.Rectangle; 
import java.awt.Color; 
import java.awt.Graphics; 

public BufferedImage crop(BufferedImage src, Rectangle rect) 
{ 
    BufferedImage dest = new BufferedImage(rect.getWidth(), rect.getHeight(), BufferedImage.TYPE_ARGB_PRE); 
    Graphics g = dest.getGraphics(); 
    g.drawImage(src, 0, 0, rect.getWidth(), rect.getHeight(), rect.getX(), rect.getY(), rect.getX() + rect.getWidth(), rect.getY() + rect.getHeight(), null); 
    g.dispose(); 
    return dest; 
} 

Конечно, вы должны сделать свой собственный JComponent:

import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import javax.image.BufferedImage; 
import java.awt.Rectangle; 
import java.awt.Graphics; 
import javax.swing.JComponent; 

public class JImageCropComponent extends JComponent implements MouseListener, MouseMotionListener 
{ 
    private BufferedImage img; 
    private int x1, y1, x2, y2; 

    public JImageCropComponent(BufferedImage img) 
    { 
     this.img = img; 
     this.addMouseListener(this); 
     this.addMouseMotionListener(this); 
    } 

    public void setImage(BufferedImage img) 
    { 
     this.img = img; 
    } 

    public BufferedImage getImage() 
    { 
     return this; 
    } 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     g.drawImage(img, 0, 0, this); 
     if (cropping) 
     { 
      // Paint the area we are going to crop. 
      g.setColor(Color.RED); 
      g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2)); 
     } 
    } 

    @Override 
    public void mousePressed(MouseEvent evt) 
    { 
     this.x1 = evt.getX(); 
     this.y1 = evt.getY(); 
    } 

    @Override 
    public void mouseReleased(MouseEvent evt) 
    { 
     this.cropping = false; 
     // Now we crop the image; 
     // This is the method a wrote in the other snipped 
     BufferedImage cropped = crop(new Rectangle(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2)); 
     // Now you have the cropped image; 
     // You have to choose what you want to do with it 
     this.img = cropped; 
    } 

    @Override 
    public void mouseDragged(MouseEvent evt) 
    { 
     cropping = true; 
     this.x2 = evt.getX(); 
     this.y2 = evt.getY(); 
    } 

    //TODO: Implement the other unused methods from Mouse(Motion)Listener 

} 

я не проверял. Возможно, есть некоторые ошибки (я не уверен во всем импорте).

Вы можете положить crop(img, rect) в этом классе. Надеюсь, это поможет.

+1

для ответа но он дает много ошибок! Можно ли сказать мне простой код для обрезки изображения? – Hussain

123

Решение, которое я нашел наиболее полезным для обрезки буферизованного изображения, использует getSubImage (x, y, w, h);

Моя кадрирование процедура закончилась выглядеть так:

private BufferedImage cropImage(BufferedImage src, Rectangle rect) { 
     BufferedImage dest = src.getSubimage(0, 0, rect.width, rect.height); 
     return dest; 
    } 
+44

почему бы не включить координаты x & y. 'BufferedImage dest = src.getSubimage (rect.x, rect.y, rect.width, rect.height);' – Sorter

29

Есть два потенциально серьезной проблемой с ведущим ответом на этот вопрос. Во-первых, в соответствии с Документах:

общественного BufferedImage getSubimage (INT х, у Int, Int W, INT ч)

Возвращает SubImage, определенный указанной прямоугольной области. Возвращенный BufferedImage использует тот же массив данных, что и исходное изображение .

По сути, это означает, что результат от getSubimage действует как указатель, который указывает на части исходного изображения.

Почему это важно? Ну, если вы планируете редактировать субимость по какой-либо причине, редактирование также произойдет с исходным изображением. Например, я столкнулся с этой проблемой, когда использовал небольшое изображение в отдельном окне, чтобы увеличить исходное изображение. (вроде как увеличительное стекло). Я позволил инвертировать цвета, чтобы увидеть некоторые детали более легко, но область, которая была «увеличена», также была перевернута в исходном изображении! Таким образом, была небольшая часть исходного изображения с инвертированными цветами, а остальная часть оставалась нормальной. Во многих случаях это не имеет значения, но если вы хотите отредактировать изображение или хотите просто получить копию обрезанного раздела, вам может потребоваться рассмотреть метод.

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

Попробуйте это:

BufferedImage img = image.getSubimage(startX, startY, endX, endY); //fill in the corners of the desired crop location here 
BufferedImage copyOfImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB); 
Graphics g = copyOfImage.createGraphics(); 
g.drawImage(img, 0, 0, null); 
return copyOfImage; //or use it however you want 

Этот метод даст вам обрезанное изображение, которое вы ищете само по себе, без обратной ссылки на исходное изображение. Это сохранит целостность исходного изображения, а также сохранит накладные расходы памяти для хранения большего изображения. (Если вы сбрасываете исходное изображение позже)

6
File fileToWrite = new File(filePath, "url"); 

BufferedImage bufferedImage = cropImage(fileToWrite, x, y, w, h); 

private BufferedImage cropImage(File filePath, int x, int y, int w, int h){ 

    try { 
     BufferedImage originalImgage = ImageIO.read(filePath); 

     BufferedImage subImgage = originalImgage.getSubimage(x, y, w, h); 



     return subImgage; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
}