Come specificare il comportamento di Java BufferedImage ridimensionare: necessità min per le righe di pixel invece di media
-
23-09-2019 - |
Domanda
Vorrei ridimensionare un BufferedImage Java, rendendolo più piccolo verticalmente ma senza utilizzare alcun tipo di media, in modo che se un pixel-fila è "vuoto" (bianco) nell'immagine sorgente, ci sarà un sui pixel bianco riga nella posizione corrispondente dell'immagine di destinazione: l'operazione "min". Gli algoritmi di default (specificati nel getScaledInstance ) non mi permettono un controllo sufficiente a grana fine. Vorrei implementare la logica seguente:
for each pixel row in the w-pixels wide destination image, d = pixel[w]
find the corresponding j pixel rows of the source image, s[][] = pixel[j][w]
write the new line of pixels, so that d[i] = min(s[j][i]) over all j, i
Ho letto su RescaleOp , ma non hanno capito come implementare questa funzionalità - è certamente un tipo strano di ridimensionamento. Qualcuno mi può fornire indicazioni su come fare questo? Nel caso peggiore, immagino posso solo prenotare l'ImageBuffer destinazione e copiare i pixel seguenti pseudocodice, ma mi chiedevo se non v'è modo migliore.
Soluzione
I metodi RescaleOp includono un parametro chiamato RenderingHints. C'è un accenno chiamato KEY_INTERPOLATION
che decide il colore da utilizzare durante il ridimensionamento di un'immagine.
Se si utilizza il valore per il VALUE_INTERPOLATION_NEAREST_NEIGHBOR
KEY_INTERPOLATION, Java utilizzeranno i colori originali, invece di usare un certo tipo di algoritmo per ricalcolare i nuovi colori.
Così, invece di linee bianche svolta al grigio o qualche combinazione di colore, si otterrà sia linee bianche, o non sarà possibile ottenere le linee a tutti. Tutto dipende il fattore di scala, e se si tratta di una riga pari o dispari. Ad esempio, se si sta ridimensionando metà, quindi ogni linea orizzontale 1 pixel presenta almeno una variazione del 50% di apparire nella nuova immagine. Tuttavia, se le linee bianche sono state due pixel in altezza, si avrebbe una probabilità del 100% della linea bianca che appare.
Questo è probabilmente il più vicino si sta andando ad ottenere oltre a scrivere il proprio metodo di scala. Purtroppo, non vedo altri suggerimenti che potrebbero aiutare ulteriormente.
Per implementare il proprio metodo di scala, è possibile creare una nuova classe che implementa l'interfaccia BufferedImageOp
, e implementare il metodo filter()
. Utilizzare getRGB()
e setRGB()
sull'oggetto BufferedImage per ottenere i pixel dell'immagine originale e impostare i pixel sulla nuova immagine.