Changer la résolution d'une image

Bonsoir,
Je suis à la recherche d'un moyen simple pour changer la résolution d'une image. Par exemple si celle-ci à une résolution de 300 ppp, je voudrais fabriquer des images de mêmes dimensions (et qui représentent la même chose!) mais avec une résolution moins élevée, par exemple 50 ppp, 72 ppp, etc.
Comment faire ?

Réponses

  • Bonjour,

    Il y a divers moyens. En ligne de commande, le programme 'convert' d'ImageMagick ('magick convert' sous Windows) peut faire cela. En Python, il y a des bibliothèques comme Pillow (que j'ai utilisée il y a... un moment). Ce petit extrait de la doc. d'ImageMagick peut aider :
    The -density option sets an attribute and does not alter the underlying raster image. It may be used to adjust the rendered size for desktop publishing purposes by adjusting the scale applied to the pixels. To resize the image so that it is the same size at a different resolution, use the -resample option.

    Je crois que la commande :
    convert entrée.png -resample 50 sortie.png
    
    (par exemple) fait ce que tu souhaites.
  • Bonjour et merci,
    En attendant de réussir à installer MagickMalik sur mon mac j'ai trouvé cette page.
    J'aimerais bien faire une petite animation montrant que l'image est plus précise, détaillée, lorsque la résolution augmente. On peut faire un programme avec Python ?
    1. Choisir une image que l'on a le droit de modifier et de diffuser, y compris pour les versions modifiées (je prends ici pour l'exemple cette ravissante bestiole sous licence CC-0).
    2. Faire en sorte que si un pixel de l'image est affiché sur exactement un pixel de l'écran, l'image occupe une place raisonnable à l'écran. C'est très simple à faire avec Gimp ou équivalent (PhotoShop, etc.). Avec Gimp, ça se passe dans le menu Image -> Scale Image. Exporter en format .png ou .gif (File -> Export As dans Gimp). (Les formats supportés par la classe PhotoImage de Tk sont PGM, PPM, GIF et PNG. Si l'on veut en utiliser d'autres avec cette même classe, il faudra probablement installer Pillow ou équivalent.) Il peut être pratique d'indiquer une puissance de 2 comme résolution de l'image avant de sauver (« exporter » dans le jargon de Gimp). Pour les captures d'écran ci-dessous, j'ai rééchantillonné l'image en 1024×680 et décrété que sa résolution était alors 128×128 dpi (tout ceci dans le menu Image -> Scale Image). Donner à cette image le suffixe -0 pour s'y retrouver ; par exemple, image-0.png.
    3. Préparer quelques versions de la même image rééchantillonnée à des résolutions plus basses, soit avec un outil comme Gimp, soit comme expliqué dans mon précédent message. Par exemple, avec un shell Unix assez standard, on peut faire (testé avec Zsh) :
      for i in $(seq 1 7); do convert image-0.png -resample $(echo "128 / 2^$i" | bc) "image-$i.png"; done
      
      pour convertir image-0.png en image-1.png, image-2.png, ..., image-7.png en divisant la résolution par 2 à chaque étape. On peut diviser par d'autres facteurs que 2, mais à moins d'installer et utiliser Pillow ou équivalent, il faut diviser par des facteurs entiers, car c'est tout ce que supporte la méthode PhotoImage.zoom() de Tkinter.
    Une fois qu'on a toutes ses images classées par ordre de résolution décroissante, par exemple, image-0.png, image-1.png, image-2.png, ..., image-7.png, on lance :
    python3 démo-rééchantillonnage.py image-*.png
    
    Si le shell est pourri, écrire le nom de chaque image en séparant par des espaces :
    python3 démo-rééchantillonnage.py image-0.png image-1.png image-2.png image-3.png image-4.png image-5.png image-6.png image-7.png
    
    Et voilà, image-0.png est affichée. En appuyant sur une touche autre que 'q' ou en cliquant dans la fenêtre, le programme passe à l'image suivante. Si :
    • on appuie sur 'q' ou ;
    • on clique ou appuie sur une touche quelconque alors qu'on a déjà vu toutes les images ;
    le programme affiche un message exprimant sa tristesse et se termine.
    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import locale
    import sys
    
    import tkinter as tk
    from tkinter import ttk
    from tkinter.messagebox import showinfo
    
    class App:
    
        def __init__(self):
            self.imageIndex = 0
            self.firstImageWidth = None
            self.firstImageHeight = None
            self.firstImage = True
    
            self.root = tk.Tk()
            self.frame = ttk.Frame(self.root)
            self.frame.winfo_toplevel().title("Démo de rééchantillonnage")
    
            self.label = ttk.Label(self.frame)
            self.setImage(self.imageIndex)
            self.label.bind("<Key>", self.onKeypress)
            self.label.bind("<Button-1>", self.onClicked)
            self.label.pack()
            self.frame.pack()
            self.label.focus_set()
    
        def onKeypress(self, event):
            if event.char.lower() == "q":
                self.quit()
            else:
                self.action()
    
        def onClicked(self, event):
            self.action()
    
        def action(self):
            if self.imageIndex >= len(sys.argv) - 2:
                showinfo("Terminé", "Il n'y a plus d'image à montrer. Cassos.")
                self.quit()
            else:
                self.imageIndex += 1
                self.setImage(self.imageIndex)
    
        def setImage(self, index):
            image = tk.PhotoImage(file=sys.argv[1+index])
    
            if self.firstImage:
                self.firstImageWidth  = image.width()
                self.firstImageHeight = image.height()
                self.firstImage = False
            else:
                image = image.zoom(
                    x=round(self.firstImageWidth / image.width()),
                    y=round(self.firstImageHeight / image.height()))
    
            self.label.image = image # garder une référence
            self.label.configure(image=image)
    
        def mainLoop(self):
            self.root.mainloop()
    
        def quit(self):
            self.root.quit()
    
    
    def main():
        locale.setlocale(locale.LC_ALL, '')
        App().mainLoop()
        sys.exit(0)
    
    if __name__ == "__main__": main()
    
    Je n'inclus pas la totalité des captures d'écran, il me semble que l'on comprend assez bien ainsi.96708
    96712
    96716
    96718
    96720
    96724
Connectez-vous ou Inscrivez-vous pour répondre.