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