I’m using GDI+ to scale my UI graphics, specifically GdipSetInterpolationMode.
[code] Function ScalePicture(p as picture, width as integer, height as Integer) As picture
Dim res as new picture(width,height) #if TargetWin32 then
// tell GDI+ to do quality scaling
Soft Declare Function GdipSetInterpolationMode Lib “Gdiplus” (graphics as int32, Mode as int32) As int32
Call GdipSetInterpolationMode(res.graphics.Handle(Graphics.HandleTypeGDIPlusGraphics), 8) #endif
res.Graphics.DrawPicture(p, 0, 0, width, height, 0, 0, p.width, p.height)
return res
End Function
[/code]
Made ZERO code changes, just a compile in 2016r2 to see the new retina changes on Windows.
A low DPI scaled at higher DPI will look jagged. You may want to update your picture with a new one, entered as an image at three resolutions. 75 DPI, 150 DPI and 300 DPI at the same image size. Or a picture at 150 DPI (in my own tests, either way works well)
The image is loaded at 150, 300 and 600 dpi (I have it larger because the user can scale the window up to full screen and the image needs to scale with it).
Everything worked acceptably in 2016 r1.1. Something changed between then and now.
What has changed is that now full HiDPI support means the pictures dragged into the project are immutable and that can explain the issue if you pass the picture as is.
You may want to first draw p into an intermediary picture before passing it to your declare.
Actually, reading again your code, what happens if you simply comment the two lines pertaining to the declare ?
Michel is probably right (as is often the case!). Xojo tries to handle the interpolation itself. It is possible that the call to GdipSetInterpolationMode is superfluous and actully play a role in the issue. That escaped me on the first read.
I removed the GdipSetInterpolationMode calls and it’s drawn identically (still poorly). It’s almost as if GDI Plus is skipped by the new framework. I have verified that the switch IS still on in the Windows build settings.
The whole reason I was using GDI Plus to scale the image was that the scaling algorithm is much smoother than the internal Xojo one, which downscales unacceptably ugly IMHO. If there is an alternative, I’m all ears.
[quote=276931:@Christian Wheel]I removed the GdipSetInterpolationMode calls and it’s drawn identically (still poorly). It’s almost as if GDI Plus is skipped by the new framework. I have verified that the switch IS still on in the Windows build settings.
The whole reason I was using GDI Plus to scale the image was that the scaling algorithm is much smoother than the internal Xojo one, which downscales unacceptably ugly IMHO. If there is an alternative, I’m all ears.[/quote]
That thread is where the ScalePicture method in my OP came from. Unfortunately it seems to be broken in 2016r2. The alternative solutions in that thread either compromise quality or speed.
I suspect I won’t be the last to complain about this and hope that another solution is discovered (or ideally at some point Xojo includes high-quality scaling in the framework). Pre-Scaled pictures are not an option for my app as the pictures scale dynamically as the user resizes the window.
In the meantime, I’m using the MBS scaling function, which seems to be better-looking than Xojo scaling, but it also can antialias which helps quite a bit. It’s still not great (these same images look fantastic using the internal downscaling in .NET apps), but it’s acceptable.
Here’s the revised function in case it helps anyone else.
Function ScalePicture(p as picture, width as integer, height as Integer) As picture
Dim res as new picture(width,height)
res=p.ScaleImageAndMaskMBS(width, height, true, 0)
return res
End Function
I think the issue has to do with the new HiDPI Support that somehow broke the declare. It should not be out of this world to come up with a new way to use GdipSetInterpolationMode. Since this seems to bother you quite a bit, maybe if you ask very nicely @jim mckay in PM, he will be able to adapt his code.
That said, this shows the limit of free and voluntary declare code, which can be quite fragile. Whereas well supported plugins like MBS are reliable, and come with a great service.
If I had to take a random, unresearched guess, it would be that GdipSetInterpolationMode can’t understand the new Picture format (hi-dpi with multiple resolutions) and there would have to be some translation to a standard bitmap before passing the handle off to the api.
@jim mckay , if you ever decide to update your code, I would be in your debt if you would be willing to share it.
Once I finish some of the more vital aspects of my app’s logic I too will revisit this issue and try to find a better solution.
That is not it. I tried the declare in non HiDPI mode, and the result is the same. I would suspect there was a change in the way Xojo calls the system to resize the picture, since in the end the code calls a standard Xojo code resize.
It should be possible to carry out the entire resize process inside the declare.