2010-03-05 53 views
60

Quiero recortar una imagen manualmente con el mouse.
Supongamos que la imagen tiene algo de texto, y quiero seleccionar algo de texto de una imagen, luego para ese propósito. Quiero recortar esa área con el mouse.¿Cómo recorto una imagen en Java?

+0

Varias buenas ideas a continuación. Vea también http://java.sun.com/docs/books/tutorial/2d/ – trashgod

+0

Hussain: dé una de estas respuestas detalladas al cheque – IcedDante

Respuesta

2

Necesita leer acerca de la API de imagen de Java y la API relacionada con el mouse, tal vez en algún lugar bajo el paquete awt.event.

Para empezar, debe poder cargar y visualizar la imagen en la pantalla, quizás use un JPanel.

Luego, desde allí, intentará implementar una interfaz de escucha de movimiento de mouse y otras interfaces relacionadas. Tal vez tengas atado en el método mouseDragged ...

Para una acción mouseDragged, obtendrá la coordenada de la forma rectangular por el arrastre ...

A continuación, a partir de estas coordenadas, obtendrá la subimagen de la imagen que tiene y la vuelve a dibujar de nuevo ...

y luego muestra la imagen recortada ... no sé si esto funcionará, solo un producto de mi imaginación ... solo ¡un pensamiento!

+0

gracias su sugerencia cómo puedo establecer la imagen en el applet usando el Panel para recortar – Hussain

6

Esta pregunta no tiene suficiente información para responder. Una solución general (dependiendo de su marco de GUI): agregue un controlador de eventos de mouse que captará los clics y los movimientos del mouse. Esto le dará sus coordenadas (x, y). Luego usa estas coordenadas para recortar tu imagen.

+0

gracias voy a intentarlo – Hussain

9

Este es un método que trabajará:

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; 
} 

Por supuesto que tiene que hacer su propia 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 

} 

no he probado él. Tal vez haya algunos errores (no estoy seguro de todas las importaciones).

Puede poner el método crop(img, rect) en esta clase. Espero que esto ayude.

+1

gracias por darme la respuesta pero da muchos errores! ¿me puede decir un código fácil para recortar una imagen? – Hussain

123

La solución que encontré más útil para recortar una imagen en el búfer utiliza getSubImage (x, y, w, h);

Mi rutina de cultivo terminó pareciéndose a esto:

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

por qué no incluir también las coordenadas xey. 'BufferedImage dest = src.getSubimage (rect.x, rect.y, rect.width, rect.height);' – Sorter

29

hay dos potencialmente importante problema con el líder respuesta a esta pregunta. En primer lugar, según los documentos:

público BufferedImage getSubimage (int x, int y, int w, int h)

Devuelve una subimagen definido por una región rectangular especificada. La imagen Buffered devuelta comparte la misma matriz de datos que la imagen original .

Básicamente, lo que esto significa es que el resultado de getSubimage actúa como un puntero que apunta a una subsección de la imagen original.

¿Por qué es esto importante? Bueno, si planea editar la subimagen por cualquier motivo, las ediciones también le sucederán a la imagen original. Por ejemplo, me encontré con este problema cuando estaba usando la imagen más pequeña en una ventana separada para acercar la imagen original. (algo así como una lupa). Permití invertir los colores para ver ciertos detalles más fácilmente, ¡pero el área que se "amplió" también se invirtió en la imagen original! Entonces, había una pequeña sección de la imagen original que tenía colores invertidos, mientras que el resto permanecía normal. En muchos casos, esto no importará, pero si desea editar la imagen, o si solo desea una copia de la sección recortada, es posible que desee considerar un método.

Lo que nos lleva al segundo problema. Afortunadamente, no es un problema tan grande como el primero. getSubImage comparte la misma matriz de datos que la imagen original. Eso significa que toda la imagen original aún está almacenada en la memoria. Suponiendo que al "recortar" la imagen realmente quiere una imagen más pequeña, tendrá que volver a dibujarla como una nueva imagen en lugar de simplemente obtener la subimagen.

Prueba esto:

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 

Esta técnica le dará la imagen recortada que busca por sí mismo, sin el enlace a la imagen original. Esto preservará la integridad de la imagen original y le ahorrará la sobrecarga de memoria para almacenar la imagen más grande. (Si va a volcar la imagen original más adelante)

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; 
    } 
} 
Cuestiones relacionadas