Domanda

Sono un programmatore Java ragionevolmente con esperienza, ma relativamente nuova per Java2D. Sto cercando di ridimensionare l'immagine, ma sto ottenendo risultati di scarsa qualità. L'immagine è solo un'anteprima di un pannello in modo contiene cose come testo e campi di testo. Io sarò sempre ridimensionamento verso il basso, mai in su.

Attualmente sto utilizzando il seguente codice: -

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);

Dove panelImage rappresenta l'anteprima pieno di dimensioni (BufferedImage) e scaledWidth e scaledHeight sono le rispettive dimensioni di destinazione. Mi sembra di perdere un sacco di dettagli nel testo e bordi di cose come campi di testo, ecc.

C'è una chiamata meglio dovrei usare per ridimensionare l'immagine?

Grazie, John

È stato utile?

Soluzione

Un suggerimento che posso fare è ridimensionare prima l'immagine su un separato BufferedImage . Il motivo è, un href="http://java.sun.com/javase/6/docs/api/java/awt/Graphics2D.html" rel="noreferrer"> Graphics2D oggetto della BufferedImage può essere ottenuto in modo da produrre un'immagine di qualità migliore scalata.

Graphics2D può accettare "suggerimenti di rendering" che istruire l'elaborazione delle immagini modo deve essere eseguita dall'oggetto Graphics2D. Il metodo setRenderingHint è uno dei metodi che possono essere utilizzati per impostare le note di rendering. I suggerimenti di rendering della classe RenderingHints possono essere usato.

Quindi, utilizzando quell'oggetto Graphics2D, un'immagine può essere attirata sulla BufferedImage utilizzando i suggerimenti di rendering specificate in precedenza.

Un codice di massima (non testato) potrebbe funzionare come il seguente:

BufferedImage scaledImage = new BufferedImage(
    scaledWidth,
    scaledHeight,
    BufferedImage.TYPE_INT_RGB
);

Graphics2D g = scaledImage.createGraphics();
g.setRenderingHints(
    RenderingHints.Key.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();

Altri suggerimenti di rendering di interesse possono includere:

La sezione Controllo qualità di rendering di Java Tutorial ha anche ulteriori informazioni su come controllare la qualità di rendering degli oggetti Graphics2D.

E per una buona fonte di informazioni su come affrontare le interfacce grafiche in generale, Filthy Rich Client da Chet Haase e Romain Guy è altamente raccomandato. V'è una sezione del libro che tratta il tema delle immagini di scala, che sembra piuttosto rilevanti.

Altri suggerimenti

Può essere che si dovrebbe chiamare:

 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

e

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Coobird è giusto che è necessario in modo incrementale down-scala (preferibilmente utilizzando Bicubica) per ottenere un risultato di bell'aspetto per una piccola miniatura abbastanza. Image.getScaledInstance usato per fare questo con l'approccio AREA_AVERAGED, ma è molto più lento del downscale incrementale che è stato proposto originale di Chris Campbell nel suo "Perils of Image.getScaledInstance ()" articolo.

Chiedo scusa per l'auto-promozione qui, ma ho arrotolato una manciata di "Java migliori pratiche nativi" quando si tratta di un'immagine in scala in una libreria chiamata imgscalr .

E 'disponibile sotto una licenza Apache 2 e la fonte è tutto su GitHub; l'obiettivo della biblioteca è stato quello di rendere l'immagine-scala nella nativa Java morto-facile (1 classe, 5 metodi statici) e garantire il miglior risultato alla ricerca (che è quello che in origine voleva), il risultato più veloce (grande quando ridimensionamento tra immagini di grandi dimensioni ) o di un equilibrio tra i due e lasciare che la biblioteca decidere quale usare.

Volevo solo un lib che potrebbe "Resize mia immagine e uscire dalla mia strada" e dopo aver letto tutti questi posti per un paio di giorni come ho affrontato il punto di dolore (la mia pure) appena girava indietro e la condivisione della lavorare per chiunque altro può aiutare.

Coobird ha l'idea giusta. Vorrei anche provare RenderingHints.VALUE_INTERPOLATION_BILINEAR interpolazione e vedere se è più bello guardare. Bicubica funziona meglio quando upscaling, però. Per ottenere i migliori risultati quando downscaling, si dovrebbe downscale in più fasi . In primo luogo dimezzare la risoluzione, poi dimezzare di nuovo, ecc fino ad arrivare nei pressi della risoluzione desiderata (vale a dire non si può dimezzare o l'immagine si ottiene troppo piccola). Passo finale è quello di scalare verso il basso per la risoluzione desiderata.

Per esempio, diciamo che la vostra immagine di ingresso è 800x600 e si desidera rimpicciolire a 160x120 :

  1. Downscale 50% . -> 400x300
  2. Downscale 50% . -> 200x150
  3. Downscale a 160x120 .
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top