Ich habe Code geschrieben, um eine Windows-Bitmap zu lesen und möchte sie nun mit ltk anzeigen. Wie kann ich ein entsprechendes Objekt konstruieren? Gibt es eine solche Funktionalität in ltk? Wenn nicht, wie kann ich es direkt über eine Schnittstelle zu tk machen?
Antworten
Zu viele Anzeigen?Es ist schon eine Weile her, dass ich LTK für irgendetwas verwendet habe, aber der einfachste Weg, ein Bild mit LTK anzuzeigen, ist wie folgt:
(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)))))
Leider sind die Möglichkeiten, die Sie mit dem Bild standardmäßig haben, ziemlich begrenzt, und Sie können nur gif- oder ppm-Bilder verwenden - aber die ppm-Dateiformat ist sehr einfach, Sie können aus Ihrer Bitmap problemlos ein ppm-Bild erstellen. Allerdings sagen Sie, Sie wollen das angezeigte Bild zu manipulieren, und Blick auf den Code, der das Bild-Objekt definiert:
(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)
Es sieht so aus, als ob die tatsächlichen Daten für das Bild vom Tcl/Tk-Interpreter gespeichert werden und nicht von Lisp aus zugänglich sind. Wenn Sie darauf zugreifen wollten, müßten Sie wahrscheinlich Ihre eigenen Funktionen schreiben, indem Sie Format-Wunsch y send-wish .
Natürlich könnten Sie einfach jedes Pixel einzeln auf einem Canvas-Objekt rendern, aber ich glaube nicht, dass Sie dabei eine sehr gute Leistung erzielen würden. Das Canvas-Widget wird ein bisschen langsam, sobald Sie versuchen, mehr als ein paar tausend verschiedene Dinge darauf anzuzeigen. Zusammenfassend kann man also sagen: Wenn Sie nichts in Echtzeit machen wollen, können Sie Ihre Bitmap jedes Mal, wenn Sie sie anzeigen wollen, als .ppm-Bild speichern und sie dann einfach mit dem obigen Code laden - das wäre das Einfachste. Andernfalls könnten Sie versuchen, auf die Daten von tk selbst zuzugreifen (nachdem Sie sie einmal als ppm-Bild geladen haben), und wenn das alles nicht funktioniert, könnten Sie zu einem anderen Toolkit wechseln. Die meisten vernünftigen Lisp-GUI-Toolkits sind für Linux, wenn Sie also Windows benutzen, haben Sie möglicherweise Pech.
Tk unterstützt von Haus aus keine Windows-Bitmap-Dateien. Die "Img"-Erweiterung unterstützt diese jedoch und ist auf fast jeder Plattform frei verfügbar. Sie brauchen die Daten nicht einzulesen, sondern können das Bild direkt aus der Datei auf der Festplatte erstellen. In einfachem tcl/tk könnte Ihr Code etwa so aussehen:
package require Img
set image [image create photo -file /path/to/image.bmp]
label .l -image $image
pack .l
Weitere Informationen finden Sie unter http://wiki.tcl.tk/6165