Imago est une bibliothèque de manipulation d'image pour le LISP commun. Il prend en charge les images dans PNG, PCX, Portable Bitmap (.PNM), TrueVision TGA (.TGA) et JPEG. Vous pouvez lire une image avec imago:read-image et écrire une image avec imago:write-format où format est celui de png , pcx , pnm , tga ou jpg .
Vous pouvez utiliser une bibliothèque Libjpeg-Turbo plus avancée pour traiter les fichiers JPEG en chargeant le système imago/jpeg-turbo . Assurez-vous que libjpeg-turbo est installé sur votre système. Utilisez imago-jpeg-turbo:read-jpg-turbo et imago-jpeg-turbo:write-jpg-turbo (ou simplement imago:read-image et imago:write-image ) pour utiliser cette fonctionnalité.
Vous pouvez utiliser une bibliothèque PNGLoad plus avancée et plus rapide pour lire les fichiers PNG en chargeant le système imago/pngio . Utilisez imago-pngio:read-png (ou simplement imago:read-image ) pour utiliser cette fonctionnalité. NB: pngload convertit automatiquement les images couleur indexées en images RVB (ou Argb). Si vous souhaitez travailler avec des images indexées, utilisez plutôt l'ancien chargeur PNG. La bibliothèque ZPNG (via imago-pngio:write-png ) sera utilisée pour enregistrer les images PNG.
Pour créer une image, regardez la documentation des classes d'images (comme imago:rgb-image ou imago:grayscale-image ). Vous devez faire une instance de l'une de ces classes en passant :w , :h et éventuellement :initial-color pour make-instance . Alternativement, vous pouvez utiliser des fonctions make-XXX-image et make-XXX-image-from-pixels :
;; Create 100x100 px black grayscale image
(imago:make-grayscale-image 100 100)
;; Create 400x100 px red RGB image
(imago:make-rgb-image 400 100 (imago:make-color 255 0 0))
;; Create 400x100 px half-transparent red RGB image
(imago:make-rgb-image 400 100 (imago:make-color 255 0 0 127))
;; Create an image from an array of pixels
(imago:make-rgb-image-from-pixels
(make-array '(100 100)
:element-type 'imago:rgb-pixel
:initial-element (imago:make-color 0 255 255)))
La plupart des exemples sont pris à partir d'ici.
(resize *image* 400 150)
| Original | Traité |
|---|---|
![]() | ![]() |
(rotate *image* 45)
| Original | Traité |
|---|---|
![]() | ![]() |
(emboss *image* :angle (* pi 0.75) :depth 1.0)
| Original | Traité |
|---|---|
![]() | ![]() |
(let ((kernel #2A((0 0 0 0 0)
(0 0 1 0 0)
(0 1 -4 1 0)
(0 0 1 0 0)
(0 0 0 0 0))))
(convolve *image* kernel 1 0))
| Original | Traité |
|---|---|
![]() | ![]() |
(do-region-pixels (*image* color x y 70 65 140 125)
(setf color (invert-color color)))
| Original | Traité |
|---|---|
![]() | ![]() |
(enhance-contrast *grayscale-image*)
| Original | Traité |
|---|---|
![]() | ![]() |
(do-image-pixels (*image* color x y)
(multiple-value-bind (r g b) (color-rgb color)
(setf color (make-color b
(floor (* g 0.8))
r))))
| Original | Traité |
|---|---|
![]() | ![]() |
(let ((operator (default-compose-operator *image1*)))
(compose nil *image1* *image2* 20 20 operator))
| Original 1 | Original 2 | Traité |
|---|---|---|
![]() | ![]() | ![]() |
(let ((points '(83 45 73 150 73 150 198 106 198 106 83 45)))
(draw-polygon *image* points +white+ :closed t))
(draw-circle *image* 83 45 15 +white+)
(draw-circle *image* 73 150 15 +white+)
(draw-circle *image* 198 106 15 +white+)
(draw-bezier-curve *image* 10 80 150 60 100 170 200 170 +red+)
(draw-line *image* 0 5 254 5 +yellow+)
(draw-line *image* 0 10 254 10 +yellow+ :dash-length 1 :dash-interval 1)
(draw-line *image* 0 15 254 15 +yellow+ :dash-length 4 :dash-interval 2)
| Original | Traité |
|---|---|
![]() | ![]() |
(defun sea-view (image)
(let ((image2 (flip nil image :horizontal)))
(do-image-pixels (image2 color x y)
(multiple-value-bind (r g b)
(color-rgb color)
(setf color (make-color (floor r 3) (floor g 3) (floor b 2)))))
(let* ((width (image-width image))
(height (image-height image))
(result (make-instance (class-of image)
:width width :height (* height 2))))
(copy result image)
(copy result image2 :dest-y height)
result)))
| Original | Traité |
|---|---|
![]() | ![]() |
Cet exemple nécessite des serpents et des systèmes d'opérations de tableau (disponibles dans QuickLisp).
(defpackage components-example
(:use #:cl
#:snakes
#:imago)
(:export #:convert-to-image))
(in-package :components-example)
(defgenerator generate-colors ()
(loop while t do
(yield (make-color (random 256)
(random 256)
(random 256)))))
(defgenerator black ()
(yield (make-color 0 0 0)))
(defun convert-to-image (components)
(declare (type (simple-array fixnum (* *)) components))
(let ((colors (take (1+ (reduce #'max (aops:flatten components)))
(chain (black)
(generate-colors))))
(image (make-array (array-dimensions components)
:element-type 'rgb-pixel)))
(array-operations/utilities:nested-loop (i j)
(array-dimensions components)
(setf (aref image i j)
(nth (aref components i j) colors)))
(make-instance 'rgb-image :pixels image)))
(in-package :cl-user)
(let* ((image (imago:read-image "~/.quicklisp/local-projects/imago/tests/spheres.png"))
(components (imago:label-components (imago:convert-to-binary image 1))))
(components-example:convert-to-image components))
| Original | Traité |
|---|---|
![]() | ![]() |
Calcul de la transformée de distance euclidienne au carré (également une transformée de distance de Manhattan est disponible). Cet exemple nécessite array-operations .
(defun edt-image (image)
(declare (type imago:binary-image image))
(let* ((dt (imago:distance-transform image :type :edt))
(max (reduce #'max (aops:flatten dt)))
(pixels (make-array (array-dimensions dt) :element-type 'imago:grayscale-pixel)))
(map-into (aops:flatten pixels)
(lambda (x) (imago:make-gray (floor (* 255 x) max)))
(aops:flatten dt))
(make-instance 'imago:grayscale-image :pixels pixels)))
(edt-image original-image)
| Original | Traité |
|---|---|
![]() | ![]() |
Vous pouvez afficher les images Imago dans Jupyter en installant le système imago/jupyter . Ensuite, appelez imago-jupyter:show-image Fonction pour montrer une image.
