[PB 5.61 beta 1] Bug in SpriteQuality or in the PNG decoder

Just starting out? Need help? Post your questions and find answers here.
Armoured
Enthusiast
Enthusiast
Posts: 348
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

[PB 5.61 beta 1] Bug in SpriteQuality or in the PNG decoder

Post by Armoured »

Hi,
This program write a PNG image of a black square (Test.png) and load it in a transparent sprite.
The resulting sprite is displayed using the bilinear filter provided from Purebasic and the square is rotated to show the antialiasing effect.
The problem is that the filter generate grey dots detached from the black square shape (you can stop the rotation pressing the key "2" to see it better) this dots aren't in the saved PNG file. :?

Code: Select all

InitSprite()
InitKeyboard()
UsePNGImageDecoder()
UsePNGImageEncoder()

flag.b = #True
flag_rot.b = #True

If (OpenScreen(640, 480, 32, "Test Bug", #PB_Screen_SmartSynchronization , 60))
    SetFrameRate(60)
    
    If (CreateSprite(2001, 256, 256,#PB_Sprite_AlphaBlending))
        StartDrawing(SpriteOutput(2001))
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box(2,2,254,254,RGBA(1,1,1,255))
        StopDrawing()
        SaveSprite(2001,"Test.png", #PB_ImagePlugin_PNG)
    EndIf
    
    SpriteQuality(#PB_Sprite_BilinearFiltering)
    LoadSprite(2002,"Test.png")
    rotation = 0
    
    Repeat
        ClearScreen(RGBA(255,255,255,255))
        
        If flag_rot
            rotation + 1
            RotateSprite(2002, rotation, #PB_Absolute)
        EndIf
        
        StartDrawing(ScreenOutput())
        
        If (flag)
            DrawText(0,20,"SpriteQuality On (Press 1 to change)",RGB(0,0,0),RGB(255,255,255))
        Else
            DrawText(0,20,"SpriteQuality Off (Press 1 to change)",RGB(0,0,0),RGB(255,255,255))
        EndIf
        
        If (flag_rot)
            DrawText(0,40,"Sprite rotation On (Press 2 to change)",RGB(0,0,0),RGB(255,255,255))
        Else
            DrawText(0,40,"Sprite Rotation Off (Press 2 to change)",RGB(0,0,0),RGB(255,255,255))
        EndIf
        StopDrawing()
        
        DisplayTransparentSprite(2002,640 / 2 - SpriteWidth(2002) / 2,480 / 2 - SpriteHeight(2002) / 2,255)
        FlipBuffers()
        
        ExamineKeyboard()
        
        If KeyboardReleased(#PB_Key_1)
            If flag = #False
                SpriteQuality(#PB_Sprite_BilinearFiltering)
                flag = #True
            Else
                SpriteQuality(#PB_Sprite_NoFiltering)
                flag = #False
            EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_2)
            If flag_rot = #False
                flag_rot = #True
            Else
                flag_rot = #False
            EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_Escape)
            CloseScreen()
            End
        EndIf
    ForEver
EndIf
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by DK_PETER »

Try:

Code: Select all

Box(2,2,252,252,RGBA(1,1,1,255))
instead of

Code: Select all

Box(2,2,254,254,RGBA(1,1,1,255))
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Armoured
Enthusiast
Enthusiast
Posts: 348
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Armoured »

DK_PETER wrote:Try:

Code: Select all

Box(2,2,252,252,RGBA(1,1,1,255))
instead of

Code: Select all

Box(2,2,254,254,RGBA(1,1,1,255))
Thanks!
Ok this work but why? Is a bug or not?
User avatar
Demivec
Addict
Addict
Posts: 4089
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Demivec »

Not directly related to your question but still incorrect, this line is incorrect:

Code: Select all

ClearScreen(RGBA(255,255,255,255))
The ClearScreen() command only works with RGB() colors, it's clearing the screen, not overwriting it :) . It should be:

Code: Select all

ClearScreen(RGB(255,255,255))
Armoured
Enthusiast
Enthusiast
Posts: 348
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Armoured »

Demivec wrote:Not directly related to your question but still incorrect, this line is incorrect:

Code: Select all

ClearScreen(RGBA(255,255,255,255))
The ClearScreen() command only works with RGB() colors, it's clearing the screen, not overwriting it :) . It should be:

Code: Select all

ClearScreen(RGB(255,255,255))
Thanks again but you know anything about the original question?
User avatar
Demivec
Addict
Addict
Posts: 4089
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Demivec »

Armoured wrote:Thanks again but you know anything about the original question?
With regard to your original question and in my humble opinion, no it is not a bug.

When the sprite (or any image for that matter) is blended with the surrounding pixels a method is used that combines the colors of 2 or more pixels. Usually it is a square block.

The problem areas are the edges and corners of the image, especially in a rotated image. This is true because if you're blending each pixel with the ones one each side for instance (top, bottom, left, right, plus corners), on an edge you're missing 3 out of 9 pixels to compute the blended value. On a corner it is worse, you're missing 5 out of 9 possible pixels.

In your test code these problem areas blended the black pixels with the alpha pixels to generate a grey color and it is evident near the diagonal edges of a rotated image.

I am not sure how many pixels are used, nor the exact manner in which they are blended when using SpriteQuality(#PB_Sprite_BilinearFiltering). But by giving the desired content of the sprite, the black box, an extra pixel of border width of the desired alpha value you are then ensuring that the problems areas shouldn't crop up. This is because even on the problem areas such a corner the pixels that remain (the 5 out of 9) will contain the proper values for blending. In other words if pixels are going to be missing from the equation let it be the extra pixels that aren't needed anyway.

I am not sure if there is any other viable solution to this problem outside of a custom one like DK_PETER suggested. I don't think it is a bug, just a natural consequence of the blending method.
Armoured
Enthusiast
Enthusiast
Posts: 348
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Armoured »

Demivec wrote:
Armoured wrote:Thanks again but you know anything about the original question?
With regard to your original question and in my humble opinion, no it is not a bug.

When the sprite (or any image for that matter) is blended with the surrounding pixels a method is used that combines the colors of 2 or more pixels. Usually it is a square block.

The problem areas are the edges and corners of the image, especially in a rotated image. This is true because if you're blending each pixel with the ones one each side for instance (top, bottom, left, right, plus corners), on an edge you're missing 3 out of 9 pixels to compute the blended value. On a corner it is worse, you're missing 5 out of 9 possible pixels.

In your test code these problem areas blended the black pixels with the alpha pixels to generate a grey color and it is evident near the diagonal edges of a rotated image.

I am not sure how many pixels are used, nor the exact manner in which they are blended when using SpriteQuality(#PB_Sprite_BilinearFiltering). But by giving the desired content of the sprite, the black box, an extra pixel of border width of the desired alpha value you are then ensuring that the problems areas shouldn't crop up. This is because even on the problem areas such a corner the pixels that remain (the 5 out of 9) will contain the proper values for blending. In other words if pixels are going to be missing from the equation let it be the extra pixels that aren't needed anyway.

I am not sure if there is any other viable solution to this problem outside of a custom one like DK_PETER suggested. I don't think it is a bug, just a natural consequence of the blending method.
Ok this explanation is sufficient for me!
Thanks again to all that have answered to this question :)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by netmaestro »

Bilinear filtering relies on interpolation of the values in neighboring pixels, not only adjacent but further away as well. The pixels on the edge of the box quite simply need more data for the interpolations than a 2px border provides. The addition of a couple of extra rows/columns gives the algorithm enough room to work. DK_PETER's solution is the correct one.
BERESHEIT
Armoured
Enthusiast
Enthusiast
Posts: 348
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Re: [PB 5.61 beta 1] Bug in SpriteQuality or in the PNG deco

Post by Armoured »

netmaestro wrote:Bilinear filtering relies on interpolation of the values in neighboring pixels, not only adjacent but further away as well. The pixels on the edge of the box quite simply need more data for the interpolations than a 2px border provides. The addition of a couple of extra rows/columns gives the algorithm enough room to work. DK_PETER's solution is the correct one.
Ok netmaestro! Thanks for the clarification :)
Post Reply