2010-03-05 14 views
60

Voglio ritagliare manualmente un'immagine usando il mouse.
Supponiamo che l'immagine abbia del testo e voglio selezionare del testo da un'immagine, quindi lo a tale scopo voglio ritagliare quell'area usando il mouse.Come ritagliare un'immagine in Java?

+0

Diverse buone idee di seguito. Vedi anche http://java.sun.com/docs/books/tutorial/2d/ – trashgod

+0

Hussain: dare una di queste risposte dettagliate al controllo – IcedDante

risposta

2

È necessario leggere su Java Image API e API relative al mouse, magari da qualche parte nel pacchetto awt.event.

Per iniziare, devi essere in grado di caricare e visualizzare l'immagine sullo schermo, forse userai un JPanel.

Poi da lì, proverai a implementare un'interfaccia listener di movimento del mouse e altre interfacce correlate. Forse avrai legato al metodo mouseDragged ...

Per un'azione mouseDragged, si otterrà la coordinata della forma rettangolare dalla resistenza ...

Poi da queste coordinate, si otterrà il sottoimmagine dall'immagine che hai e lo ridisegni di nuovo ...

e quindi visualizzare l'immagine ritagliata ... non so se questo funzionerà, solo un prodotto della mia immaginazione ... solo un pensiero!

+0

ringrazia il tuo suggerimento come posso impostare l'immagine sull'applet usando il pannello per il ritaglio – Hussain

6

Questa domanda non ha informazioni sufficienti per rispondere. Una soluzione generale (a seconda del framework della GUI): aggiungi un gestore di eventi del mouse che catturerà i clic e i movimenti del mouse. Questo ti darà le coordinate (x, y). Quindi usa queste coordinate per ritagliare la tua immagine.

+0

grazie proverò per questo – Hussain

9

questo è un metodo che funziona:

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

Naturalmente dovete fare il vostro proprio 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 

} 

non ho la prova di esso. Forse ci sono degli errori (non sono sicuro di tutte le importazioni).

È possibile inserire il metodo crop(img, rect) in questa classe. Spero che questo aiuti.

+1

grazie per aver risposto ma dà molti errori! puoi dirmi un codice facile per ritagliare un'immagine? – Hussain

123

La soluzione che ho trovato più utile per ritagliare un'immagine bufferizzata utilizza getSubImage (x, y, w, h);

La mia routine ritaglio finito simile a questo:

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

perché non includere anche le coordinate x & y. 'BufferedImage dest = src.getSubimage (rect.x, rect.y, rect.width, rect.height);' – Sorter

29

ci sono due potenzialmente grave problema con la risposta che porta a questa domanda. In primo luogo, secondo la documentazione:

pubblico BufferedImage getSubimage (int x, int y , int w, int h)

Ritorna una sottoimmagine definito da una regione rettangolare specificata. Il file restituito BufferedImage condivide lo stesso array di dati dell'immagine originale .

In sostanza, ciò significa che il risultato di getSubimage agisce come un puntatore che punta ad una sottosezione dell'immagine originale.

Perché è importante? Bene, se hai intenzione di modificare l'immagine secondaria per qualsiasi motivo, le modifiche si verificheranno anche sull'immagine originale. Per esempio, mi sono imbattuto in questo problema quando stavo usando l'immagine più piccola in una finestra separata per ingrandire l'immagine originale. (un po 'come una lente d'ingrandimento). Ho reso possibile invertire i colori per vedere più facilmente determinati dettagli, ma l'area "zoomata" è stata invertita anche nell'immagine originale! Quindi c'era una piccola sezione dell'immagine originale che aveva invertito i colori mentre il resto rimaneva normale. In molti casi, non importa, ma se vuoi modificare l'immagine, o se vuoi solo una copia della sezione ritagliata, potresti prendere in considerazione un metodo.

Che ci porta al secondo problema. Fortunatamente, non è un grosso problema come il primo. getSubImage condivide lo stesso array di dati dell'immagine originale. Ciò significa che l'intera immagine originale è ancora memorizzata. Supponendo che "ritaglia" l'immagine in realtà desideri un'immagine più piccola, dovrai ridisegnarla come una nuova immagine piuttosto che ottenere l'immagine secondaria.

Prova questo:

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 

Questa tecnica vi darà l'immagine ritagliata che stai cercando da sola, senza il link all'immagine originale. Ciò preserverà l'integrità dell'immagine originale e ti farà risparmiare la memoria generale di memorizzazione dell'immagine più grande. (Se si esegue il dump dell'immagine originale in seguito)

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