Graphics.AntiAliasMode Not working with Windows Web 1.0 (2019R3.2)

I did some testing for storing photos in a MySQL database a few days ago starting with an MBS Example and then modified code to get scaling with Antialiasing to work and was happy with the result using the method below:

Public Function ScalePicture(p As Picture, maxWidth As Integer, maxHeight As Integer) as Picture
  // Scales a Picture while keeping the correct aspect ratio
  If p <> Nil Then
    
    // Calculate the scale ratio
    Dim ratio As Double = min(maxHeight / p.height, maxWidth / p.width)
    
    // Create a new picture to return
    Var w As Integer = p.width * ratio
    Var h As Integer = p.height * ratio
    Dim newPic As New Picture(w, h, 32)
    
    // Scale the Picture using Graphics.AntiAliasMode
    newPic.Graphics.AntiAlias = True
    newPic.Graphics.AntiAliasMode = Global.Graphics.AntiAliasModes.HighQuality
    
    // Draw the picture in the new size
    newPic.graphics.DrawPicture(p, 0, 0, w, h, 0, 0, p.width, p.height)
    
    Return newPic
    
  End If
End Function

The result from scaling two images one that was 4032 x 3024 and another 3024 x 4032 to Thumnail images with a max dimension of 180 pixels were smooth and retained detail.

content1D cover1D

However, using the exact same function in a web application the scaling is jagged and horrible.

content1W cover1W

I’ve been searching for an alternate and reading through as many forum posts as I can find on scaling with antialiasing but I haven’t found any solution that gave me equivalent quality comparable to the Thumbnails generated with the Desktop Graphics.AntiAliasMode.

Potentially there appears to be something called D2D1 from a post with an exchange by Norman Palardy and William Yu about a replacement for GDI+ but there wasn’t actually any syntax for a D2D1 Soft Declare.

So far I’ve had no better results with all the MBS options I’ve tried and I’m assuming that Graphics.AntiAliasMode is broken in Web 1.0, but if someone knows why it isn’t working and has a fix I’d sure like to hear about that, otherwise if anyone has a better option for scaling down high res images to quality thumbnails I’d sure like to to get your recommendation or sample code.

Quite a while I did an implementation of native rescaling. Let me search my old code.

Edit: found the code. I don’t know if this works for web or not.

Private Function BilinearInterpolation(OriginalPicture as Picture, newWidth as Integer, newHeight as Integer, constrainProportion as Boolean) As Picture
  
  dim w as Integer = OriginalPicture.Width
  dim h as Integer = OriginalPicture.Height
  dim x_ratio as Double = (w - 1)/newWidth
  dim y_ratio as Double = (h - 1)/newHeight
  if constrainProportion then
    if x_ratio >= y_ratio then
      newHeight = h/x_ratio
    else
      newWidth = w/y_ratio
    end if
    x_ratio = max(x_ratio, y_ratio)
    y_ratio = max(x_ratio, y_ratio)
  end if
  
  dim oldSurf as RGBSurface = OriginalPicture.RGBSurface
  dim oldMask as Picture = OriginalPicture.CopyMask
  dim oldMaskSurf as RGBSurface 
  if oldMask <> nil then oldMaskSurf = OriginalPicture.mask.RGBSurface
  dim InterpolatedPicture as new Picture(newWidth, newHeight, 32)
  dim InterpolatedSurf as RGBSurface = InterpolatedPicture.RGBSurface
  dim InterpolatedMaskSurf as RGBSurface = InterpolatedPicture.mask.RGBSurface
  
  dim x, y as Integer
  dim x_diff, y_diff, blue, red, green, gray as Double
  dim a, b, c, d as Color
  
  for i as Integer = 0 to (newHeight - 1)
    for j as Integer = 0 to (newWidth - 1)
      x = x_ratio * j
      y = y_ratio * i
      x_diff = (x_ratio * j) -x
      y_diff = (y_ratio * i) - y
      
      'calculations for red, green and blue
      a = oldSurf.Pixel(x, y)
      b = oldSurf.Pixel(x + 1, y)
      c = oldSurf.Pixel(x, y + 1)
      d = oldSurf.Pixel(x + 1, y + 1)
      
      blue = (a.Blue * (1 - x_diff) * (1 - y_diff)) + (b.Blue * x_diff * (1 - y_diff)) + (c.Blue * y_diff * (1 - x_diff)) + (d.Blue * x_diff * y_diff)
      green = (a.green * (1 - x_diff) * (1 - y_diff)) + (b.green * x_diff * (1 - y_diff)) + (c.green * y_diff * (1 - x_diff)) + (d.green * x_diff * y_diff)
      red = (a.red * (1 - x_diff) * (1 - y_diff)) + (b.red * x_diff * (1 - y_diff)) + (c.red * y_diff * (1 - x_diff)) + (d.red * x_diff * y_diff)
      
      InterpolatedSurf.Pixel(j, i) = Color.RGB(red, green, blue)
      
      if oldMaskSurf <> Nil then
        'now the mask
        a = oldMaskSurf.Pixel(x, y)
        b = oldMaskSurf.Pixel(x + 1, y)
        c = oldMaskSurf.Pixel(x, y + 1)
        d = oldMaskSurf.Pixel(x + 1, y + 1)
        
        gray = (a.Blue * (1 - x_diff) * (1 - y_diff)) + (b.Blue * x_diff * (1 - y_diff)) + (c.Blue * y_diff * (1 - x_diff)) + (d.Blue * x_diff * y_diff)
        
        InterpolatedMaskSurf.Pixel(j, i) = Color.RGB(gray, gray, gray)
      end if
    next
    
  next
  
  Return InterpolatedPicture
  
End Function

AntiAlias only works on desktop.

Hi Beatrix,

Thanks for the code snippet. Your code is now the second version of bilinear interpretation with RGBSurface I’ve tried with no success in quality change. I think there must be something fundamentally broken in Web 1.0 Picture manipulation especially since Greg O’Lone confirmed that AntiAlias only works in desktop apps. My guess is that the complier doesn’t reject using the desktop commands for Picture, but they somehow are ignored in execution. I get equally bad results using various plugins that worked on a desktop app so the logic is Web app pictures can’t be effectively manipulated. In any case the quality with your code looks like the result I get trying to use plugins and Graphics.AntiAliasMode in the Web 1.0 app.

content1Beatrix

And the goal is to achieve this:

content1D

I did a test late yesterday where I created a console app with 2021R2.1 that processes an Image using the Graphics.AntiAliasMode and I get the desired quality. I’m working on shelling out to that app in my web app to process the thumbnails and resizing large uploaded photos to the medium res storage limit I have set at 2048 x 2048. Once stored, using the ScalePicture code in my original post to display a photo in a dynamically sized palette window looks good enough for the purposes of the App.

–Tom

That is very odd. The code produces smooth rescaled images on desktop. There is nothing that is using anti-aliasing in the code.

The first image looks like a nearest neighbor and not the bilinear.

Perhaps Greg O’Lone can confirm that RGBSurface also only works on desktop like AntiAlias only works on desktop. That might explain the result.

It used to be documented somewhere that the graphics system in Console apps is different from that of Desktop. Try drawing text, the positioning is wildly different.

Windows has just always been terrible at resizing images. Are plugins a solution for this project? MBS may be worth a shot.

Tried them. Results are no better in the Web app. They work fine in the desktop.

Change this to .AntiAliased

Admittedly that was wrong due to a copy paste error but it makes no difference and the Compiler didn’t complain about a syntax error. I just tested it and the result is the same in Web 1.0 as before changing it.

Very odd indeed, I have it working here and I initially though it was that causing the issue. I guess this web stuff is more buggy that I thought, I only ever use Web when I’m checking bugs and I’ve think I’ve found two just helping you here.

This is what I see with it working:

image

and this is with it not working

image

this is altered simply by commenting out line 14 in your code from above.

If you breakpoint on line 19 (the Return) of ScalePicture and view newPic in the debugger does it look smooth or jaggy?

If its jaggy are you able to dropbox/host the image you’re testing and PM me the link?

Are you testing using 2019R3.2 to build your test Web app or are you testing in Web 2.0 2020R1 or higher?

When I view it in the debugger it is Jaggy. If you can confirm that you definitely are using 2019R3.2 and testing in a web app I’d be happy send you a link to the image.

Awwww shuzzbut, correct version helps :wink: Let me see.

Yeah its borked, let me see if I can whip something up for you to at least salvage some of your wasted time on me :wink:

That is mighty kind of you if you have an idea better than my current approach, which is I have created a console app with 2021R2.1 that processes an Image using the Graphics.AntiAliasMode where I get the desired quality. I’m presently working on shelling out to that app in my web app to process the thumbnails and resizing large uploaded photos to the medium res storage limit I have set at 2048 x 2048. I suspect it won’t be much slower than if Graphics.AntiAliasMode was working in Web 1.0, since the user of this app is limited to 4 picture uploads at a time.

I had a little play with this after dinner and couldn’t find an easy way around it so your method is probably the simplest method. I did find the bug report regarding this issue and it was fixed in the very next version after the one you’re using <https://xojo.com/issue/20033>. In web everything uses libgd but there’s no documentation on which version xojo is using, I can get a handle to the image with ConsoleGDImage but without re-wrapping libgd and including it with your project it doesn’t seem that there’s a way around the bug.

I’m not really sure why MBS options produce the same result, maybe Christian can shed some light on that if you contact him directly.

There are several different MBS functions that relate to scaling. Maybe you used the wrong one.

I would be looking at the PictureMBS based scaling functions (Monkeybread Xojo plugin - PictureMBS) or maybe the GraphicsMagick plugin.