2012-02-04 15 views
5

Ci sono un paio di domande simili su SO, ma nessuno di loro ha veramente aiutato. Fondamentalmente sto cercando di ridimensionare una semplice immagine png, come si vede qui:Ridimensionamento png trasparente con Python Image Library e l'effetto alone

http://media.spiralknights.com/wiki-images/3/3e/Equipment-Proto_Sword_icon.png (dal mmo Spiral Knights, diritti d'autore tre anelli Entertainment)

mi aveva inizialmente implementato un programma di utilità che utilizza queste immagini in php, e l'utilità di ridimensionamento ha funzionato perfettamente. Ho usato il metodo descritto nella pagina imagecopyresampled nella documentazione di PHP.

Onestamente non riesco nemmeno a ridimensionarlo meglio in Photoshop, ma i risultati sono quasi disastrosi in Python. Ricevo costantemente un effetto alone, e credo che questo sia almeno in parte rispetto ai reali valori RGBA dei pixel trasparenti. Ecco, questa immagine dice meglio:

resize examples

(la penultima ridimensionamento era solo un suggerimento che ho visto su un altro forum per ridimensionare prima a due volte la dimensione finale, ed ha aiutato almeno un po ', ma non sufficiente)

L'immagine è già in modalità RGBA quando viene ridimensionata.

Come potete vedere le ridimensionazioni di PHP e Photoshop sono senza alone. Onestamente tutto, eccetto il ridimensionamento PHP, funziona troppo, mi piace la palette minima nell'immagine php (se guardi le versioni più grandi puoi vedere che il ridimensionamento di PHP usa meno tra i colori), ma potrei vivere con il modo in cui Photoshop lo ha ridimensionato, o anche la parte interna del python ridimensiona, ma l'alone è inaccettabile.

Mi sembra - e correggo se ho torto - che PHP e Photoshop sembrano sapere di non usare il colore dei pixel nel canale alfa quando interpolano, ma python usa quel bordo chiaro, che è altrimenti trasparente, nel suo ridimensionamento.

Purtroppo ci sono molte icone diverse che ho bisogno di ridimensionare, con profili diversi, quindi non sono tutte così semplici come quelle circolari, ma questo era solo il primo che stavo usando mentre sperimentavo.

non è molto di una domanda di codice in sé e per sé, ma se avete bisogno di qualcosa da guardare, allora questo è il succo:

>> import Image 
>> img = Image.open('swordorig.png') 
>> img 
<PngImagePlugin.PngImageFile image mode=RGBA size=256x256 at 0x2A3AF58> 
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png') 

Eventuale domanda dell'essere: c'è un modo per dire PIL NON usa il colore di un pixel che ha un alfa di 0 durante il ricampionamento?

+0

Non conoscendo PIL, ma hai provato a utilizzare RGBa (non RGBA) per istruirlo a considerare l'immagine come alfa premoltiplicata? – rotoglup

+1

Non l'ho fatto, quindi grazie per il suggerimento! Sfortunatamente sembra che PIL non sia in grado di scrivere RGBa come un png. "IOError: impossibile scrivere modalità RGBa come PNG" – cogs

+0

Se ti piace il risultato di Photoshop Bicubic, forse 'Image.BICUBIC' o' Image.NEAREST' sarà migliore? http://pastebin.com/VRBKWZUh – reclosedev

risposta

6

Grazie a tutti per aver risposto! E soprattutto a rotoglup per avermi detto il termine per quello che stavo veramente cercando. Passando attraverso le pagine di overflow dello stack per alpha premoltiplicato in PIL I ho trovato una soluzione che funziona; qui è un foglio di grafica aggiornata di ridimensionamento:

resize sheet 2

Le barre grigie sono solo per dare l'impressione di quello che sarà simile su uno sfondo più chiaro.

https://stackoverflow.com/a/6882161/1189554

Grazie alla madlag

Quindi il mio codice finisce per assomigliare a questo:

>> import Image, numpy 
>> img = Image.open('swordorig.png') 
>> premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8) 
>> alphaLayer = premult[3::4]/255.0 
>> premult[::4] *= alphaLayer 
>> premult[1::4] *= alphaLayer 
>> premult[2::4] *= alphaLayer 
>> img = Image.fromstring("RGBA", img.size, premult.tostring()) 
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png') 

e si ottiene l'icona che si trova nella parte inferiore del foglio. Ancora più colori rispetto alla versione di PHP, e un anello molto mite, ma nel complesso molto, molto più bello. Sono sicuro che l'algoritmo potrebbe essere ottimizzato per migliorarlo ancora di più. Grazie ancora a tutti per aver risposto!

Problemi correlati