为画布上的图像列表设置动画

时间:2017-02-25 13:40:59

标签: image animation racket

我正在尝试使用以下代码在画布上显示图像列表。但是,出现一个空框架,直到整个' for#39;循环运行,然后最终效果显示在框架中。

#lang racket/gui
(require 2htdp/image)

(define frame (new frame%
                   [label "Example"]
                   [width  500]
                   [height 500]))

(send frame show #t) 
; (sleep 1)    ; tried this to allow time for frame to show properly; does not help; 

(new canvas% [parent frame]
     [paint-callback
      (lambda (canvas dc)
        (for ((i imglist))      ; imglist is a list of images to be displayed @ 1/second.
          (send dc clear)
          (send dc draw-bitmap 
                     (image->bitmap i) 
                     20 20)
          ; (send dc flush)     ; this statement also does not help;
          (sleep 1)             ; to show animation effect from list of images;
          ))])

image->位图函数来自:; from:https://lists.racket-lang.org/users/archive/2014-December/065110.html

(define (image->bitmap image)   
  (let* ([width (image-width image)]
         [height (image-height image)]
         [bm (make-bitmap width height)]
         [dc (send bm make-dc)])
    (send dc clear)
    (send image draw dc 0 0 0 0 width height 0 0 #f)
    bm))

问题在哪里以及如何解决?

2 个答案:

答案 0 :(得分:1)

paint-callback用于快速更新画布然后返回。 当它返回时,系统知道画布已更新。

执行所需操作的一种方法:1)引入一个保存当前显示图像的参数。 2)使paint-callback绘制当前图像。 3)创建一个单独的线程,每秒更改当前图像。

注意:下面我在image->bitmap中为宽度和高度添加了+1。圆圈的边缘被切断了。

#lang racket/gui
(require 2htdp/image)

(define images (list (circle 30 "outline" "red")
                     (circle 20 "outline" "red")
                     (circle 10 "outline" "red")
                     (circle  5 "outline" "red")))

(define current-image (make-parameter (first images)))

(define (image->bitmap image)   
  (let* ([width  (+ (image-width  image) 1)]
         [height (+ (image-height image) 1)]
         [bm     (make-bitmap width height)]
         [dc     (send bm make-dc)])
    (send dc clear)
    (send image draw dc 0 0 0 0 width height 0 0 #f)
    bm))

(define frame (new frame%
                   [label "Example"]
                   [width  500]
                   [height 500]))

(define canvas (new canvas% [parent frame]
                    [paint-callback
                     (lambda (canvas dc)
                       (send dc clear)
                       (send dc draw-bitmap (image->bitmap (current-image)) 20 20))]))

(send frame show #t) 

(thread (λ ()
          (let loop ([is images])
            (cond
              [(null? is) (loop images)]
              [else       (current-image (first is))
                          (send canvas on-paint)
                          (sleep 1)
                          (loop (rest is))]))))

答案 1 :(得分:0)

以下作品:

(define images (list (circle 30 "outline" "red")
                     (circle 20 "outline" "red")
                     (circle 10 "outline" "red")
                     (circle  5 "outline" "red")))

(define (image->bitmap image)  
  (let* ([width (image-width image)]
         [height (image-height image)]
         [bm (make-bitmap width height)]
         [dc (send bm make-dc)])
    (send dc clear)
    (send image draw dc 0 0 0 0 width height 0 0 #f)
    bm))

(define frame (new frame% [label "Frame"] [width 300] [height 300]))
(define canvas (new canvas% [parent frame]))
(define dc (send canvas get-dc))

(send frame show #t)
(sleep/yield 1)

(let loop ()  
  (for ((i images))
    (send dc clear)
    (send dc draw-bitmap
          (image->bitmap i)
          20 20)
    (sleep 0.5))
  (loop))

但是,显示动画的帧不会关闭,但必须从IDE停止。