Be_Giant(mob/M as mob in world)
set desc = "Testing Scale Proc"
set category = "Testing"

var/bigme = input("Enter a multiplier","Giant Size Me") as null|num

var/icon/i = icon(M.icon)

i.Scale(bigme * i.Width(),bigme * i.Height())

M.icon = i
M.pixel_x = ((i.Width() - 32) / 2)*-1


Problem description:

The code above works fine. It asks the user for a number, it multiplies the user's icon size by that multiplier, and then sets their pixel_x to center them. That's not the issue I'm having.

I just noticed this but, the Developer Reference says the following...

"Scale() automatically performs antialiasing to avoid unwanted artifacts."

But it doesn't seem to do that when enlarging an icon. Only when shrinking it. If you increase the size of the icon, if its not a multiple of its current size, the icon will be distorted.

You get an effect like when you enlarge an icon in photoshop and use the preserve hard edges option where the pixels are stretched with no blending between them to smooth the transition.

That's increasing the icon's scale from 32x32 to 48x48

Doesn't really look like Anti-Aliasing to me?
Maybe that's because of the size wich is too small. Perhaps you have PIXEL_SCALE as an appearance_flag aswell
I dont think its the size that's the problem. If anything, the smaller icons need the anti-aliasing more.

Here's going from 32 to 230 and 32 to 16.

Going smaller gives you the color blending and transparency around the edges, but going bigger gives you very clear hard lines.
Use transform instead of icon procs. It's best to use transform over icon procs when you can. Icon procs are more for when you plan to save the modified icon to a new file, since dynamic icons basically create a new file inside the resource cache when you display them, requiring clients to download the new dynamic icon files before they can see them. Transform is just 6 numbers that clients use to tell their GPU how to render something, and is very efficient and doesn't bloat the resource cache.
var matrix/t = new
t.Translate(0, 16)
t.Translate(0, -16)
M.transform = t

Since matrix scaling happens around the center of the icon, the Translate calls keep the bottom of the icon in the same place by moving the bottom to the center, scaling, and moving back. The horizontal center already stays the same.

PIXEL_SCALE is an appearance_flag that disables anti-aliasing from transforms. You'd want to leave that off.