Keep white interactive background when saving pict to png file

I want to format some trees into png files. This code from StackOverflow makes a great diagram in the interactive window. When I follow the suggestion in the comment to save to a file, the png ends up with a solid black background. Can someone help with changing the saved png to a white background?

#lang racket

;; https://stackoverflow.com/questions/54621805/visualize-arbitrary-tree-in-racket-using-tree-layout

(require pict
         pict/tree-layout)

(define (draw tree)
  (define (viz tree)
    (cond
      ((null? tree) #f)
      ((not (pair? tree))
       (tree-layout #:pict (cc-superimpose
                            (disk 30 #:color "white")
                            (text (symbol->string tree)))))
      ((not (pair? (car tree)))
       (apply tree-layout (map viz (cdr tree))
              #:pict (cc-superimpose
                      (disk 30 #:color "white")
                      (text (symbol->string (car tree))))))))
  (if (null? tree)
      #f
      (naive-layered (viz tree))))

(define t1 '(and (or x1 x2) (or x3 x4 x5)))

(draw t1)

(define generated-pict (draw t1))

(send (pict->bitmap generated-pict) save-file "example.png" 'png)


1 Like

It is likely that the PNG has a transparent background, as this is the default, and the tool you use to view the PNG uses black as the background.

My own preferred way to solve this problem is to add an explicit rectangle to the pict, which acts as the background -- you can control the color. However, the pict->bitmap function has a #:make-bitmap parameter and you can pass a lambda to create a bitmap without an alpha channel.

Edit: I suppose , I should provide an example :slight_smile:

(define generated-pict (draw t1))

(define bg
 (filled-rectangle (pict-width generated-pict) (pict-height generated-pict)
                   #:color "yellow" 
                   #:draw-border? #f))

;; Save this one to PNG
(define pict-with-background (cc-superimpose bg generated-pict))

Alex.

1 Like

Thanks so much!

Is there a simple way to emit svg intead of png?

I use this function I wrote some time ago. the inset parameter allows specifying a border to the SVG, but you can set that to 0.

You can aslo change svg-dc% to pdf-dc% to generate PDF documents:

(define (pict->svg pict inset file-name)
  (let* ((w (+ inset inset (pict-width pict)))
         (h (+ inset inset (pict-height pict)))
         (dc (new svg-dc% [width w] [height h]
                  [output file-name]
                  [exists 'truncate/replace])))
    (send dc start-doc "export to file")
    (send dc start-page)
    (draw-pict pict dc inset inset)
    (send dc end-page)
    (send dc end-doc)))