3
votes

Comment puis-je réduire la taille du fichier d'une image PNG sans changer ses dimensions?

Je souhaite réduire la taille d'un fichier PNG en utilisant Python. J'ai parcouru beaucoup de matériel sur Internet, mais je n'ai rien trouvé où je réduirais la taille du fichier d'une image sans changer les dimensions, c'est-à-dire hauteur / largeur. Ce que j'ai trouvé, c'est comment changer les dimensions de l'image, en utilisant PIL ou une autre bibliothèque de Python.

Comment puis-je réduire la taille du fichier image tout en gardant ses dimensions constantes?


5 commentaires

Juste une image ou beaucoup? Veuillez partager l'image. Pourquoi veux-tu faire cela? Les disques sont bon marché.


Si l'image est en couleur, vous pouvez la convertir en niveaux de gris (c'est-à-dire jeter les informations de couleur). Le flou peut être un autre moyen de réduire le contenu des informations.


Je dois servir ces png via le Web. Alors, avez besoin d'eux en petite taille.


Si vous devez vraiment servir des fichiers PNG, essayez peut-être l'outil pngcrush .


@MarkSetchell, bien sûr .. Permettez-moi de jeter un œil là-dessus.


3 Réponses :


1
votes

PNG est un format sans perte et il consommera évidemment plus d'espace.

Si vous ne vous souciez que de la résolution, vous pouvez convertir en n'importe quelle forme avec perte comme JPG.

https://whatis.techtarget.com/definition/lossless-and-lossy-compression a >

La dimension après la conversion serait la même, mais la qualité dépend de la compression nécessaire

Extrait de code pour convertir le PNG en JPG

from PIL import Image

im = Image.open("Picture2.png")
rgb_im = im.convert('RGB')
rgb_im.save('Picture2.jpg')


1 commentaires

Je veux qu'il soit enregistré au format png. Y en a-t-il de toute façon?



2
votes

PNG est un format sans perte, mais il peut toujours être compressé sans perte. La classe d'image Pillow est fournie avec un graveur png acceptant un paramètre compress_level .

On peut facilement démontrer que cela fonctionne:

Étape 1: Charger l'image générique rgb lena au format .png:

path_compressed = './lena_compressed.png'
img.save(path_compressed,compress_level=9)
print(os.path.getsize(path_compressed))
> 406889

Étape 2 : Écrivez png avec compress_level=0:

path_uncompressed = './lena_uncompressed.png'
img.save(path_uncompressed,compress_level=0)
print(os.path.getsize(path_uncompressed))
> 691968

 img_uncompressed: 691968 octets

Étape 3: Écrivez png avec compress_level=9:

import os
import requests
from PIL import Image
from io import BytesIO

img_url = 'http://pngnq.sourceforge.net/testimages/lena.png'
response = requests.get(img_url)
img = Image.open(BytesIO(response.content))

 img_compressed: 406889 octets

ce qui dans ce cas nous donne une compression respectable de 30% sans aucune dégradation évidente de la qualité d'image (ce qui devrait être attendu pour un algorithme de compression sans perte).


2 commentaires

"sans aucune dégradation évidente de la qualité d'image" -> "sans aucune dégradation de la qualité d'image". L'image compressée et l'image d'origine contiennent exactement les mêmes informations. Une fois décompressées, les données sont identiques à 100%.


Et notez que par défaut, le fichier PNG aura probablement le niveau de compression défini sur max.



0
votes

Par défaut, la plupart des écrivains PNG utiliseront le paramètre de compression maximum, donc essayer de changer cela n'aidera pas beaucoup. Les PNG non compressés existent, mais ils n'ont aucun sens, je ne pense pas que vous en rencontrerez beaucoup.

Ainsi, le seul moyen de réduire considérablement les PNG est de réduire le nombre de pixels qu'ils stockent, ou de réduire le nombre de couleurs qu'il stocke. Vous avez spécifiquement dit de ne pas vouloir réduire le nombre de pixels, donc l'autre option est de réduire le nombre de couleurs.

La plupart des fichiers PNG seront en mode "couleurs vraies" (généralement 24 bits par pixel, avec un octet chacun pour les composantes rouge, verte et bleue de chaque pixel). Cependant, il est également possible de créer des fichiers PNG indexés. Celles-ci stockent une carte de couleurs (a.k.a. palette) et une seule valeur par pixel, l'index dans une carte de couleurs. Si, par exemple, vous choisissez une carte de couleurs de 64 entrées, chaque pixel aura besoin de 6 bits pour encoder l'index. Vous stockeriez 64 * 3 octets + 3/4 octets par pixel (qui, bien sûr, se compressent également). J'ai trouvé ce site Web en comparant quelques exemples d'images, à quoi ils ressembleraient et à quel point finit par être lors de la réduction des couleurs.

Cette autre question montre comment utiliser PIL pour convertir une image RVB en une image indexée:

img.convert("P", palette=Image.ADAPTIVE)

Cela semble générer une carte de couleurs 8 bits cependant, PIL ne prend pas en charge les cartes de couleurs plus petites. Le module PyPNG vous permettrait d'écrire des fichiers PNG avec n'importe quel nombre de couleurs dans la carte des couleurs.


0 commentaires