Как отобразить изображение с помощью ltk?
Я написал код для чтения растрового изображения Windows и теперь хотел бы отобразить его с помощью ltk. Как я могу построить соответствующий объект? Есть ли такой функционал в ltk? Если нет, то как я могу сделать это напрямую через TK?
2 ответа
Прошло много времени с тех пор, как я использовал LTK для чего-либо, но самый простой способ отобразить изображение с помощью LTK заключается в следующем:
(defpackage #:ltk-image-example
(:use #:cl #:ltk))
(in-package #:ltk-image-example)
(defun image-example ()
(with-ltk ()
(let ((image (make-image)))
(image-load image "testimage.gif")
(let ((canvas (make-instance 'canvas)))
(create-image canvas 0 0 :image image)
(configure canvas :width 800)
(configure canvas :height 640)
(pack canvas)))))
К сожалению, то, что вы можете сделать с изображением по умолчанию, довольно ограничено, и вы можете использовать только изображения в формате gif или ppm - но формат файла ppm очень прост, вы можете легко создать изображение ppm из своего растрового изображения. Однако вы говорите, что хотите манипулировать отображаемым изображением и смотрите на код, который определяет объект изображения:
(defclass photo-image(tkobject)
((data :accessor data :initform nil :initarg :data)
)
)
(defmethod widget-path ((photo photo-image))
(name photo))
(defmethod initialize-instance :after ((p photo-image)
&key width height format grayscale data)
(check-type data (or null string))
(setf (name p) (create-name))
(format-wish "image create photo ~A~@[ -width ~a~]~@[ -height ~a~]~@[ -format \"~a\"~]~@[ -grayscale~*~]~@[ -data ~s~]"
(name p) width height format grayscale data))
(defun make-image ()
(let* ((name (create-name))
(i (make-instance 'photo-image :name name)))
;(create i)
i))
(defgeneric image-load (p filename))
(defmethod image-load((p photo-image) filename)
;(format t "loading file ~a~&" filename)
(send-wish (format nil "~A read {~A} -shrink" (name p) filename))
p)
Похоже, что фактические данные для изображения хранятся интерпретатором Tcl/Tk и недоступны изнутри lisp. Если вы хотите получить к нему доступ, вам, вероятно, нужно написать свои собственные функции, используя format-wish и send-wish.
Конечно, вы можете просто визуализировать каждый пиксель на объекте canvas, но я не думаю, что при этом вы получите очень хорошую производительность, виджет canvas становится немного медленнее, когда вы пытаетесь отобразить более нескольких тысяч различных вещей на Это. Итак, подведем итог - если вам не нужно делать что-либо в реальном времени, вы можете сохранить свое растровое изображение в виде изображения.ppm каждый раз, когда захотите его отобразить, а затем просто загрузить его, используя приведенный выше код, - это будет проще всего. В противном случае вы можете попытаться получить доступ к данным из самого tk (после загрузки их один раз в виде ppm-изображения), и, наконец, если ничего из этого не сработает, вы можете переключиться на другой инструментарий. Большая часть инструментария GUI для LISP предназначена для Linux, поэтому вам может не повезти, если вы используете Windows.
Tk изначально не поддерживает растровые файлы Windows. Тем не менее, расширение "Img" делает и свободно доступно практически на любой платформе. Вам не нужно читать данные в, вы можете создать изображение прямо из файла на диске. В простом tcl / tk ваш код может выглядеть примерно так:
package require Img
set image [image create photo -file /path/to/image.bmp]
label .l -image $image
pack .l
немного больше информации можно найти на http://wiki.tcl.tk/6165