Page 1 of 1

[solved] ResizeImage() on Windows is drawing a border...

Posted: Mon Jul 04, 2016 11:30 am
by Kukulkan
Hi,

I use this small program to test:

Code: Select all

; Used with PB 5.42 LTS
Procedure test()
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Protected Path.s = "c:\temp\"
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
    Protected Path.s = "/tmp/"
  CompilerEndIf
  
  Protected img.i = CreateImage(#PB_Any, 200, 200, 
                                32, #PB_Image_Transparent)
  
  StartDrawing(ImageOutput(img.i))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  Circle(100,100,90, RGBA(200,200,200,255))
  
  StopDrawing()
  
  UsePNGImageEncoder()
  
  SaveImage(img.i, Path.s + "circlePre.png", #PB_ImagePlugin_PNG)
  
  ResizeImage(img.i, 100, 100, #PB_Image_Smooth); or use 20, 20 to see more better
  
  SaveImage(img.i, Path.s + "circlePost.png", #PB_ImagePlugin_PNG)
  
EndProcedure

test()
Linux Kubuntu 14.04 (left) and Windows 7 (right):
Image
Image

As you can see, the Windows version got a darker "line" around the circle. It looks like the resize algorithm assumed a dark background instead of a transparent one. On Linux, the result is like expected. How can I get rid of that surrounding darker line on Windows?

If you want to see the effect more drastically, simply resize to 20x20 pixels instead of 100x100. The result is annoying...

Best,

Kukulkan

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 3:41 pm
by Kukulkan
I know the result is not easy to see directly. But the thin darker line around my drawings is really annoying.

Any idea about how to get rid of this?

It becomes even worse:

Code: Select all

; Used with PB 5.42 LTS
Procedure test()
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Protected Path.s = "c:\temp\"
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
    Protected Path.s = "/tmp/"
  CompilerEndIf
 
  Protected img.i = CreateImage(#PB_Any, 20, 20,
                                32, #PB_Image_Transparent)
 
  StartDrawing(ImageOutput(img.i))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
 
  Circle(10,10,9, RGBA(200,200,200,255))
 
  StopDrawing()
 
  UsePNGImageEncoder()
 
  ResizeImage(img.i, 100, 100, #PB_Image_Smooth)
 
  SaveImage(img.i, Path.s + "circlePost.png", #PB_ImagePlugin_PNG)
 
EndProcedure

test()
Result circlePost.png:
Image

Is this a PB issue or a Windows thing? Is this only for me? Maybe my Windows? HELP!

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 4:34 pm
by Thunder93
You should also offer the circlePost.png file for testing with that code.

Oops, you right. :p

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 4:43 pm
by Kukulkan
Hi Thunder93. Why? The file is generated by the code...

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 4:44 pm
by mhs
Same result here... maybe its the antialiasing of the win api.

ResizeImage with the flag #PB_Image_Raw has no border and it happens only in combination with a transparent background.

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 4:56 pm
by Thunder93
That is the ugliest circle I have ever seen. :lol:

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 5:13 pm
by Kukulkan
Sometimes it seems it happens even if I resize images with the same size (so, no scaling happens). Any idea about how to get rid of this? It damages all my nice drawings and I need the resize function with smooth option :-( On Linux it works nice. Did not test on Mac yet...

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 5:32 pm
by Thunder93
Looks good by adding the additional flag .. #PB_Image_Raw

Code: Select all

ResizeImage(img.i, 100, 100, #PB_Image_Smooth|#PB_Image_Raw)

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 5:45 pm
by wilbert
You could change the background color but it's not a real nice solution.

Code: Select all

; Used with PB 5.42 LTS
Procedure test()
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Protected Path.s = "c:\temp\"
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
    Protected Path.s = "/tmp/"
  CompilerEndIf
  
  Protected img.i = CreateImage(#PB_Any, 200, 200, 
                                32, #PB_Image_Transparent)
  
  StartDrawing(ImageOutput(img.i))
  
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, 200, 200, RGBA(200,200,200,0))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Circle(100,100,90, RGBA(200,200,200,255))
  
  StopDrawing()
  
  UsePNGImageEncoder()
  
  SaveImage(img.i, Path.s + "circlePre.png", #PB_ImagePlugin_PNG)
  
  ResizeImage(img.i, 100, 100, #PB_Image_Smooth); or use 20, 20 to see more better
  
  SaveImage(img.i, Path.s + "circlePost.png", #PB_ImagePlugin_PNG)
  
EndProcedure

test()

Re: ResizeImage() on Windows is drawing a border...

Posted: Tue Jul 05, 2016 6:04 pm
by kenmo
I think you already figured this out, but the Resize function is working correctly.

You are interpolating opaque (light gray) foreground pixels against transparent (black!) background pixels, so the edges of the circles result in Alpha values somewhere between 0 and 255, and RGB color values somewhere between light gray and black (darker gray).

On Windows, the #PB_Image_Transparent flag fills the background with 0-alpha BLACK pixels, maybe on Linux this is filled with 0-alpha WHITE pixels?

(Then you would get a slightly LIGHTER gray border color - maybe you are not noticing this against a white background)

You can check with this:

Code: Select all

CreateImage(0, 200, 200, 32, #PB_Image_Transparent)
StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Debug "Background color = $" + RSet(Hex(Point(1, 1)), 8, "0")
  Debug ""
  Debug "Black with 0-alpha = $00000000"
  Debug "White with 0-alpha = $00FFFFFF"
StopDrawing()

Re: ResizeImage() on Windows is drawing a border...

Posted: Wed Jul 06, 2016 7:32 am
by Kukulkan
Hello,

ok, the hint about the background pixels and their opaques helped me figuring it out. I can set the background to the same colour I need for drawing except the opaque parameter (which I set to 0). This fixes my resizing issue.

Still, I'm not sure if the aliasing is correct on Windows. Sure, the background pixels are black but with opaque 0. So the aliasing should not consider their colour at all because opaque=0. On Linux, the background colour simply does not matter. I believe this is because of another (better) algorithm.

Anyway, I mark this as solved.

Thank you all! :D

Re: ResizeImage() on Windows is drawing a border...

Posted: Thu Jul 07, 2016 1:00 pm
by kenmo
Maybe we could get a confirmation that the Linux resize algorithm is different/same as Windows?
(Or maybe the RGB of #PB_Image_Transparent is different, did you test my last snippet on Linux?)
Kukulkan wrote:Sure, the background pixels are black but with opaque 0. So the aliasing should not consider their colour at all because opaque=0.
It probably shouldn't treat alpha=0 as a special case, what about when alpha=5 or even alpha=1, the input image would like essentially the same and the output would have a dark halo again.

If you Google terms like "rgba resize halo" you can find discussions about this (in other programming languages). Some sources say to calculate "associated alpha" for better results, like this:
http://entropymine.com/imageworsener/resizealpha/