Graphics.DrawPicture anti-aliasing under Cocoa

My app displays scientific images in a canvas. Under Carbon, at zoom > 100% it seems Graphics.DrawPicture simply scaled up the pixels proportionally to display the same image but say at twice the size. Cocoa wants to be clever and the same code scales up the picture but also applies anti-aliasing to smooth sharp transitions. I don’t want this because a) I’m sure it takes more time, and b) it distorts the contents of the image.
Is there a way to disable this and have the old Carbon functionality?

Peter.

Have a look at https://forum.xojo.com/10090-blurry-drawpicture . There was also a thread to get better looking images when scaling but I can’t find it at the moment.

Thanks Beatrix, Sam’s declare solution did exactly what I needed. This option should definitely be built into XOJO picture.

P.

File a feature request through Feedback.

<https://xojo.com/issue/34933>

Could it be https://forum.xojo.com/9403-scale-quality-of-canvas-control ?

possibly, but my issue is with scaling UP rather than DOWN.

I just mentioned it as Beatrix could not find it. Seems what you needed was fulfilled by Sam’s declare to find back the Carbon way.

There is more to this story: I just noticed that when:
a) the picture is scaled DOWN (ie zoom < 100%) in the canvas AND
b) the cursor is changed
the picture is drawn in a blurry manner. So this speaks to Michel’s point of blurriness when scaling DOWN.
This occurs despite bracketing with these calls:

  CGContextRef = self.imageCanvas.graphics.handle( self.imageCanvas.graphics.HandleTypeCGContextRef )
  CGContextSaveGState CGContextRef
  CGContextSetInterpolationQuality CGContextRef, 1
  myCanvas.graphics.DrawPicture ...
  CGContextRestoreGState CGContextRef

We definitely need an option to turn off all this anti-aliasing for all zooms and whether cursors are changed or not.
P.

[quote=123395:@Peter Stys]CGContextRef = self.imageCanvas.graphics.handle( self.imageCanvas.graphics.HandleTypeCGContextRef )
CGContextSaveGState CGContextRef
CGContextSetInterpolationQuality CGContextRef, 1
myCanvas.graphics.DrawPicture …
CGContextRestoreGState CGContextRef[/quote]
This should be done in the ‘Paint’ event and you should use obtain the CGContextRef from the graphics object.

Dim CGContextRef as integer = g.handle( g.handletypeCGContextRef ) 

I see: I have myCanvas.graphics.DrawPicture… or equiv calls all over the place and have been bracketing them all with your declares. This is wrong? So I should just do it once in the Paint event? Would be much easier :frowning:

p.

You should only paint in the paint event. Then call invalidate in your code when you need it.

Turns out that’s what I do: Paint event had a call that was deeply nested and I peppered all those deeper methods with the bracketing declares instead of just bracketing the original top-most call in the Paint event.

The problem:

a) the picture is scaled DOWN (ie zoom < 100%) in the canvas AND
b) the cursor is changed
the picture is drawn in a blurry manner.

persists despite adding Sam’s declares in the Paint event. Every time the cursor is changed the background bitmap is redrawn in a blurred manner. Very annoying and pretty well a show stopper for my application.

if it helps, I use this lossy method, which scales up or down without blur

[code]Function ResizeTheHardWay(oldpic as picture ,newwid as integer,newheight as integer) As picture
dim x as integer
dim y as integer
dim newpic as picture
dim newrgb as RGBSurface
dim oldrgb as RGBSurface

dim factor as double

newpic = new picture (newwid,newheight,32)
newrgb = newpic.RGBSurface
oldrgb = oldpic.RGBSurface

dim xfact as double
xfact = oldpic.width/newwid
dim yfact as double
yfact = oldpic.height/newheight

for x = 0 to newwid
for y = 0 to newheight
'get the pixel from the source and place it here
newrgb.pixel(x,y) = oldrgb.Pixel(x * xfact,y * yfact)

next

next
return newpic

End Function[/code]

[quote=123743:@Peter Stys]The problem:

a) the picture is scaled DOWN (ie zoom < 100%) in the canvas AND
b) the cursor is changed
the picture is drawn in a blurry manner.

persists despite adding Sam’s declares in the Paint event. Every time the cursor is changed the background bitmap is redrawn in a blurred manner. Very annoying and pretty well a show stopper for my application.[/quote]

Does that mean the picture is OK and it becomes blurry when the cursor changes ?

Correct, but even more mysterious: picture is DRAWN blurry not when the cursor is just changed, but when it’s changed AND then moves.

Bottom line tho, we need the Carbon behavior back ASAP.

P.

[quote=123769:@Peter Stys]Correct, but even more mysterious: picture is DRAWN blurry not when the cursor is just changed, but when it’s changed AND then moves.

Bottom line tho, we need the Carbon behavior back ASAP.[/quote]

So you get one good version, and then probably a paint event occurs and the redraw is wrong.

It would be worthwhile to track what happens with a system.debuglog in the paint event, then when you know what is going on, why not use a flag to prevent the redraw ?

As I added to Feedback Case #34933, at 16x zoom I ALWAYS get a blurry redraw. So something is fundamentally wrong with the way xojo/cocoa draws stuff and needs to be fixed ASAP.

Of course the title totally evades me at the moment so I could not find it for you but I remember clearly Dave S bumping into the same issue a while ago. And if I remember right a solution was found.

At the moment, though, and looking at the 16x image, seems possible to do enlargement without blur through RGBSurface.Pixel of the original and drawrect of each enlarged pixel at the desired size. It looks possible starting at 2x, then the bigger the picture, the easier it seems.

It is getting a bit late here, but I may give it a shot tomorrow.

It does not mean in any way that the bug report was unnecessary. Indeed it would be desirable to be able to switch off the antialiasing.