Как отобразить изображение с помощью ltk? - PullRequest
4 голосов
/ 17 сентября 2008

Я написал код для чтения растрового изображения Windows и теперь хотел бы отобразить его с помощью ltk. Как я могу построить подходящий объект? Есть ли такой функционал в ltk? Если нет, то как я могу сделать это напрямую через TK?

Ответы [ 2 ]

3 голосов
/ 19 сентября 2008

Прошло много времени с тех пор, как я использовал 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-изображения), и, наконец, если ничего из этого не сработает, вы можете переключиться на другой инструментарий. Большинство приличных наборов графических интерфейсов для lisp предназначены для linux, поэтому вам может не повезти, если вы используете windows.

2 голосов
/ 17 сентября 2008

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

...