How to save PNG with Canvas DrawInto

in the paint event u are using a windows object (Canvas1.Width) but you should use the
width and height from graphics only.
because if u use this here Canvas1.DrawInto(p.graphics the painting area is related to the given picture graphics.
to paint a smaller view into this bigger picture you can use
Var g As Graphics = p.Graphics.Clip(100,100,p.Width-200,p.Height-200)

i read you not want change all but i will mention my solution for it
canvas1

Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint
  #Pragma Unused areas
  
  DrawMe(g)
  
End Sub

button

Sub Action() Handles Action
  
  //Create the SaveAsDialog Window 
  Var dlg As SaveFileDialog
  Var f As FolderItem
  dlg = New SaveFileDialog
  dlg.Title = "Save PNG Picture File"
  dlg.SuggestedFileName = "Example 2-8 Picture.png"
  dlg.Filter = FileTypes1.PngType
  f = dlg.ShowModal
  
  If f <> Nil Then
    //Create a new picture
    Var p As New Picture(Canvas1.Width+200, Canvas1.Height+200, 32)
    p.Graphics.DrawingColor = RGB(128,0,0)
    p.Graphics.FillRectangle 0,0,p.Graphics.Width,p.Graphics.Height
    Var g As Graphics = p.Graphics.Clip(100,100,p.Width-200,p.Height-200)
    DrawMe(g)
    //Save the picture
    p.Save(f, Picture.Formats.PNG)
  End If
  
End Sub

extracted paint thing

Public Sub DrawMe(g As Graphics)
  
  g.DrawingColor = &cFFFFFF //White
  g.FillRectangle(0.0,0.0,g.Width, g.Height) //white background
  g.DrawingColor = &c000000 //Black
  g.DrawRectangle(0.0,0.0,g.Width, g.Height)
  g.DrawLine(0.0,0.0,100.0,100.0) //Draw the line
  g.DrawingColor = &c0055FF //Blue
  g.FillRectangle(120.0, 60.0, 100.0, 80.0) //Blue Rectangle
  
End Sub

Thanks for the example code @MarkusR. When I am near my development computer this weekend, I’ll work through your code.

Warm regards,

1 Like

Hi Markus,

Thanks for your suggestion and implementing the drawing to a picture.

Unfortunately, I am unable to use your nice code. This particular program has been used in legal proceedings and has over 10,000 lines of code with about 10 years of added review and simulations. There are a few hundred graphics calls, and unfortunately I cannot guarantee that they would all be correct - there are too many lines to fix.

I’ll probably just use windows, make a few declares, and make a workaround to the DrawInto bug.

Thanks for your suggestion - :slight_smile:

In the Canvas Paint event LR:
https://documentation.xojo.com/topics/user_interface/desktop/desktop_controls/canvas.html#canvas-paint

Notes

fa-exclamation-circle-32.png32x32 Directly accessing the Graphics property of the Canvas has been removed as of 2018r3. Use this event instead for all drawing.

1 Like

hmm, other minimal change at your first example would be
overwrite the graphics g,draw,and save.
but then the invalidate do not draw into the window, instead into this picture.
the dialog should be outside like your second xojo example.
if you have many copy paste canvas paint source code maybe use a own class and set super to canvas then rename the canvas super in this windows with your new class name.

Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint
  #Pragma Unused areas
  
  Var p As Picture
  If SavePicFlag = True Then
    
    //Create a new picture
    p = New Picture(Canvas1.Width+200, Canvas1.Height+200, 32)
    g = p.Graphics.Clip(100,100,p.Width,p.Height)
    
  End If
  '--------
  g.DrawingColor = &cFFFFFF //White
  g.FillRectangle(0.0,0.0,Canvas1.Width, Canvas1.Height) //white background
  g.DrawingColor = &c000000 //Black
  g.DrawRectangle(0.0,0.0,Canvas1.Width, Canvas1.Height)
  g.DrawLine(0.0,0.0,100.0,100.0) //Draw the line
  g.DrawingColor = &c0055FF //Blue
  g.FillRectangle(120.0, 60.0, 100.0, 80.0) //Blue Rectangle
  '--------
  If SavePicFlag = True Then
    SavePicFlag = False //reset to false
    
    //Create the SaveAsDialog Window 
    Var dlg as SaveFileDialog
    Var f as FolderItem
    dlg = new SaveFileDialog
    dlg.Title = "Save PNG Picture File"
    dlg.SuggestedFileName = "Example 2-8 Picture.png"
    dlg.Filter = FileTypes1.PngType
    f = dlg.ShowModal
    
    //Save the picture
    If f <> Nil Then
      p.Save(f, Picture.Formats.PNG)
    End If
    
  End If
End Sub