1

I'm writing an image processing application where I need to present to the user two images, side-by-side, in such a way that they will fit and be centered on the screen, regardless of their actual size.

I couldn't find a simple way to do this in Racket, so I am currently doing this by manually calculating and resizing the image onto another temporary bitmap.

Is there a simpler solution than this? I know that GTK4 currently has a builtin solution for this (the Gtk.Picture class draws an image without fitting to the application, but Gtk.Image does fit it, iirc).

Is there such a builtin solution in Racket?

My currect code, the important bit being canvas-original:

#lang racket/gui

(define frame (new frame% [label "Image editor"]))

(define (reset-images bitmap)
  (set! *bmp* bitmap)

  ; schedule redraw
  (send canvas-original refresh))

(define *bmp* (make-object bitmap% 50 50))

(define big-panel (new vertical-panel% [parent frame]))

; Title
(new message% [parent big-panel]
              [label "Title"]
              [font (make-font #:size 30)])

(define image-panel (new horizontal-panel% [parent big-panel] [alignment '(center center)]))

(define canvas-original
  (new canvas%
       [parent image-panel]
       [style '(transparent)]
       [paint-callback
        (lambda (canvas dc)
          (define img-w (send *bmp* get-width))
          (define img-h (send *bmp* get-height))

          (define cw (send canvas get-width))
          (define ch (send canvas get-height))

          ; calculate proper scale between the image and canvas
          (define scale (min (/ cw img-w) (/ ch img-h)))
          
          ;; calculate new scaled dimensions
          (define scaled-w (* img-w scale))
          (define scaled-h (* img-h scale))

          ; this is necessary because the real canvas dc doesn't support draw-bitmap-section-smooth
          (define canvas-size-bmp (send canvas make-bitmap cw ch))
          (define canvas-size-bmp-dc (new bitmap-dc% [bitmap canvas-size-bmp]))

          ;; calculate top-left corner to center the image
          (define x (/ (- cw scaled-w) 2))
          (define y (/ (- ch scaled-h) 2))
          (send canvas-size-bmp-dc draw-bitmap-section-smooth
                *bmp*
                x y scaled-w scaled-h ; dest
                0 0 img-w img-h)      ; src

          (send dc draw-bitmap canvas-size-bmp 0 0))]))

; image upload button
(new button% [parent big-panel]
             [label "Učitaj sliku"]
             [callback (lambda (button event)
                         (let ((filename (get-file "Učitaj sliku" frame
                                                   #f          #f       #f        null
                                                   ; directory filename extension style
                                                   '(("Images" "*.jp*g;*.png"))))) ; file filter
                           (reset-images (read-bitmap filename))))])

(send frame show #t)

The result: The resulting GUI

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.