Any way to speed this up?

SUB myDrawPicture(g as graphics, p as picture, x as integer, y as integer, w1 as integer = - 10000, h1 as integer = - 10000, sx as integer = 0, sy as integer = 0, w2 as integer = - 10000, h2 as integer = - 10000)


    Dim Interpolation_Mode As Integer
    // provided by Sam Rowlands
    Const kCGInterpolationDefault = 0
    Const kCGInterpolationNone = 1
    Const kCGInterpolationLow = 2
    Const kCGInterpolationMedium = 4
    Const kCGInterpolationHigh = 3
    //
    Interpolation_Mode=kCGInterpolationNone
    // increase "quality" on reduced images otherwise some single lines and circles seem to "disappear"
    If w2>w1 Or h2>h1 Then Interpolation_Mode=kCGInterpolationMedium ' reduced images
    //
    Declare Sub CGContextSetInterpolationQuality Lib "Cocoa" ( context As Integer, quality As Integer )
    CGContextSetInterpolationQuality( g.handle( g.HandleTypeCGContextRef ), Interpolation_Mode )
    //

  
  g.drawpicture p,x,y,w1,h1,sx,sy,w2,h2

Basically it is standard DrawPicture (last line) with a Declare to make sure it doesn’t anti-alias the image when expanded

“P” contains an picture image where I buffer all my drawing activities, and this is called from the PAINT event passing in “G” as the destination

Basically the question is… for COCOA OSX ONLY… is there some documented declares that can be used to replace DrawPicture and get the same results faster?

The response time is not too bad … until I start drawing 3600x1000 images at 50% reduction for example.

It MAY be related to changing the mode to Medium…

Sure, that’s an easy one. Instead of redrawing the picture at a reduced scale each time to the graphics object from the event, draw it into a picture object at the reduced size and then draw that picture to the event’s graphics, but keep it around for the next paint event. The real problem is all the scaling; if you scale once and cache the results, you’ll notice a dramatic speedup.

Thought of that… the problem is between Paint Events, the Picture is being updated…
So either I have to make a new reduced (or maginified) image (whichis basically what I am doing)… or I have to track the drawing actions on two pictures at two scales… which would probably take as long if not long to do…

Plus having to track when the user scrolls, changes scale etc. etc… Not sure where (or if there is true economy there or not)

I would still do it. It would significantly improve performance when scrolling especially. Changing scale, not so much.

Maybe a better question is this: when does the user experience the slowness?

I think one of us is missing the point here…

How does drawing Full Size Picture “A” into 1/2 size picture “B”, then drawing picture “B” into Canvas Graphic
become faster than
Drawing Full Size Picture “A” into Canvas Graphic at 1/2 size? the first has TWO drawpictures, the second has only ONE.

Each time Picture “A” needs to be redrawn, SOMETHING has changed… it is not redrawing the same static picture over and over

Couldn’t you do your scaling in your “drawing activities” thereby producing the image in the proper scale?

Not strictly true. If your window is sent to the background and covered, Paint will have to reconstruct the image when it gets back to the front. A static Picture would with the already-scaled image would avoid that.

That’s not quite what you asked, but is a factor in why that process would be advantageous.

There is only one “proper scale” and that is 100%… This is a drawing program. So two scales are involved. The scale of the real world image (100%) and the scale at which the user is viewing (and interacting with) it at a given moment.

After sleeping on it… I was thinking perhaps a combination of approaches.

Question… is BACKDROP persistant (as the graphics portion of a Canvas is not). Meaning if I shove an image into Backdrop, will it stay there independant of the PAINT event?

Yes.

Thanks… I think that approach will be best… I actually have TWO canvas on the screen.
The drawing canvas which changes as the user draws (duh)… and a background canvas the shows drag handles and things if the draw canvas is smaller than the window. I have just modified my code to move the background canvas to use BACKDROP instead of the PAINT event, and it is working quite nicely. (Thanks)

Now to see how much of the drawing canvas can take advantage of that method.

I will crack this nut… I always do… just a matter of time :smiley:

For what it’s worth, backdrop is literally the same as having your own Picture property and, as the first thing in the Paint event, drawing it to the graphics context.

ok… but is it faster to shove a picture into BackDrop or use DrawPicture in PaintEvent?

I would expect it to be the same.

Hey Joe! I wrote an Advanced Canvas Control for a “Photoshop written in Xojo” like application. It handle rotation, vert/horz flip of object, drag-n-drop image objects, resizing by handles, invoke objects by name (object oriented images :slight_smile: OOI), allows transparencies by default (can be disabled), features layers with move forward/backward/front/back, locking options, show/hide “incanvas locks” for locked objects, show/hide grippers and selected object outline (for static read-only loaded designs), allows user-defined drawing or object creation (not just whats hard-coded), handles undo of object removal (restore objects if they’ve been removed/deleted), export flattened canvas to PNG with or without transparencies, even saves and loads the canvas with all settings and layers (i chose xml extension in the demo saved form included). Custom resize grippers (colors or by images)…everything is customizable plus it handles resizing of images “cross-platform” with no platform specific APIs. Let me know how the resizing works (as I’ve only tested on windows and linux…have just assumed (tisk) all is ok on Mac up til this point). In the demo of the canvas I forgot to show a lot of features, I quickly just threw it together for demonstration purposes, but the original image aspects are preserved even after resize in case a “return to original” image is needed, and I didn’t demonstrate “draw on layer” with pens/colors, object alignments (like in Xojo Designer IDE), or adding properties to objects. As a full designer canvas, objects can store properties such as lets say “class name” if you were developing a visual drag-n-drop HTML editor. It is the same designer canvas I used for the iBuilder 2.0 to design iOS layouts in the IDE.

(Note: The color picker is not written by me, and is a publicly available Free control)

Download: http://www.xojodevspot.com/SimDesignerCanvas.zip

Screenshot:

yeah… I just tested it and the diff was like .0001ms per cycle which is statistically insignificant.

[quote=80713:@Dave S]I think one of us is missing the point here…

How does drawing Full Size Picture “A” into 1/2 size picture “B”, then drawing picture “B” into Canvas Graphic
become faster than
Drawing Full Size Picture “A” into Canvas Graphic at 1/2 size? the first has TWO drawpictures, the second has only ONE.

Each time Picture “A” needs to be redrawn, SOMETHING has changed… it is not redrawing the same static picture over and over[/quote]

Obviously, I don’t know what your data is or why it is changing so often. The idea was this: instead of scaling up/down Picture A each time the Paint event fires, you do it once and retain the resulting scaled image. The next time the Paint event fires, if Picture A has not changed, you simply reuse the scaled image from the previous time Paint was fired.

As long as Picture A is changing LESS than your window is being redrawn, this approach should save time.

I have found that using “Invaildate(x,y,w,h)” format speeds things up by 40-50% including the overhead to calculate what the parameters should be…