Purple Border on Image - Why?

BlitzMax Forums/BlitzMax Programming/Purple Border on Image - Why?

Hi All,

Can anyone please explain to me why I have a purple border around an image if I dont use the flag MIPMAPPEDIMAGE?



Ive read that MIPMAPPEDIMAGE requires more memory, so how can I remove this purple border without this flag?

Here is some test code:
SuperStrict

Framework BRL.GLMax2D
Import BRL.PNGLoader

SetGraphicsDriver GLMax2DDriver()


Const Screenwidth% = 320
Const Screenheight% = 240

Graphics Screenwidth, Screenheight,0
AutoMidHandle True

Local testfile$ = "gripe.run_right.png"
Local width% = 32
Local height% = 32
Local startframe% =0
Local maxframes% = 8
Local mipmappedimg:TImage = LoadAnimImage(testfile , width , height , startframe , maxframes , MIPMAPPEDIMAGE) 
Local defaultimg:TImage = LoadAnimImage(testfile, width, height, startframe , maxframes, -1)
Local filteredimg:TImage = LoadAnimImage(testfile , width , height , startframe , maxframes , FILTEREDIMAGE) 

Local frame% = 0
Local framedelay%
Local x# = Screenwidth / 2
Local y# = Screenheight / 2 - 64

Local start#
Local endtime#
Local delta#

SetClsColor 0,0,255
SetScale 2,2
Repeat

	delta = (endtime/100) - (start/100)
	 
	x:+ 1 * delta
	If x> Screenwidth x = 0
	start = MilliSecs()
	
	Cls
	framedelay:+1
	If framedelay > 5'25
		framedelay = 0
		frame:+1
		If frame => maxframes frame = 0
	End If
	DrawImage mipmappedimg, x , y , frame
	DrawImage defaultimg , x , y + 64 , frame
	DrawImage filteredimg, x, y+128 , frame
	Flip
	
	Endtime = MilliSecs()
	
Until KeyHit(KEY_ESCAPE) 


And this is the image:



Finally here is the exe/code and image in a zip:

http://therevills.syntaxbomb.com/tests/mipmappedtest.zip

Cheers!

Go to http://yanbloke.googlepages.com/ and download the DeFringe utility.

Cool... Thanks Floyd that fixes it...

So what is the "fringing"? And why does it not show up using MIPMAPPEDIMAGE?

Cheers!

PS Also is there a tool like DeFringe but allows you to select a bunch of pngs?

Found out that if I re-save my graphics using Paint.NET (v3.36) using the following options, it too removes the alpha rgb:

Bit Depth: 8-bit (the images Im using uses less the 255 colours)
Dithering Level: 7
Transparency Threshold: 128

Drag all the images into Paint.NET:

press CTRL-S (to display save), press enter (to save), press CTRL-W (to close)... repeat 200 times...my fingers are a bit tired now... (I couldnt find a batch process in Paint.NET)

I know the RAD tools can convert video, audio and image file types (in batches).. But I don't know if it allows you to change parameters on the output file type.

I normally get a white glow round images made in photoshop so I used defringe all the time. Sometimes you can't see the glow when the item is drawn at integer coords but if you move such an image slowly in increments of less that 1 pixel the glow looks pretty bad as it fluctuates.

I don't think the fringing comes from you using mipmapping, I think it comes from you NOT using filtering. It is the filtering that is smoothing out pixel values and blending them with surrounding pixels. Surely you don't get the purple glow when you use no mipmap and no filter?

Confirmed, no flags gets me no fringing: http://img12.imageshack.us/img12/8738/fringyness.png

Default flags must use filtering/mipmapping.

AutoImageFlags details the defaults which are MASKEDIMAGE and FILTEREDIMAGE. You only need to add MIPMAPPEDIMAGE if you plan to scale the image down. If you plan to draw the image at sub-pixel coords or scale it then FILTEREDIMAGE is essential - I always use it. Sometimes I've found that MIPMAPPEDIMAGE doesn't actually looks as good when some things are scaled down (e.g. bitmap fonts), or if sometimes is scaled down in an animated way you get that jump when it crosses from one mipmap to another which I don't think looks good.

Thanks for the replies guys...

RAD tools can convert video, audio and image file types (in batches)..


@Plash, thanks Ill try it out tonight... I did quite a bit of searching last night to find a batch tool for this, but didnt find any...

so I used defringe all the time


@GA, have you made a script or something for Defringe? As it would be quite time consuming to do all your graphics....

No Script, wish I had the original code as I would improve the app. I'd love it if the original author was around to make the code public...

If you wanted to make your own, it shouldn't be too hard. I would assume all it's doing is looking for pixels with less than a certain alpha threshold and then coloring them equal to the color of the nearest opaque pixel, without changing the alpha value.

If you wanted to make your own, it shouldn't be too hard.


Could you do it BlitzMax? How would your read the pixels, would it be using a pixmap (I havent really used these)?

I would assume all it's doing is looking for pixels with less than a certain alpha threshold and then coloring them equal to the color of the nearest opaque pixel, without changing the alpha value.


Sounds about right... I found this post made by the author himself:

http://www.blitzbasic.co.nz/Community/posts.php?topic=81818#922799

The 'DeFringe' program referred to here, works by simply setting the colour of all transparent pixels to the average colour of it's neighbouring opaque pixels.


The 'DeFringe' program referred to here, works by simply setting the colour of all transparent pixels to the average colour of its neighbouring opaque pixels.

Corrected grammar.

Let's petition Yan to make an update, or release the code for free, or update it and sell it, any of those 3 work for me :-)

Corrected grammar.
Why don't you just change your name to Captain Pedantic and be done with it?

Let's petition Yan to make an update, or release the code for free, or update it and sell it, any of those 3 work for me :-)


Ive started to code my own last night... with a bit of help from REDi from Syntax Bomb, its nearly there...

Ill post the code and exe soon... ;-)

Could anyone with any example images which has this problem please post them on this post....

Think its done... it may not be the neatest code, but it works pretty well....

' Multi-Defringe
' The Revills Games
' www.therevillsgames.com

SuperStrict

' dont need graphics...

' get the source folder
Local testdir$ = RequestDir("Select Source folder...", CurrentDir())
If testdir = "" Then 
	Notify "No source directory selected... ", True
	RuntimeError "No source directory selected... "
EndIf
' get the destination folder
Local savedir$ = RequestDir("Select Save folder...", CurrentDir())
If savedir= "" Then 
	Notify "No destination directory selected... ", True
	RuntimeError "No destination directory selected... "
EndIf

' read the souce folder
Local dir%=ReadDir(testdir)
If Not dir RuntimeError "failed to read current directory"

Repeat
	Local testfile$ = NextFile(dir )
	If testfile ="" Exit
	If testfile ="." Or testfile =".." Continue
		
	' only load pngs
	If Lower(ExtractExt(testfile))<> "png"
		testfile = ""
	EndIf

	If testfile>"" Then
		Local fileok% = True
		
		Print "Loading.... "+testfile
		Local image:TPixmap = LoadPixmap (testdir +""+ testfile)
		If image = Null
			Print "Error loading image..."+testfile
			fileok = False
		EndIf
		
		If fileok
			Print "Processing..."
			Local w% = PixmapWidth(image)
			Local h% = PixmapHeight(image)			
			Local array%[w,h]
			
			Local Tmp:TPixmap=CreatePixmap:TPixmap(w, h, PixmapFormat(image))
			' store the pixels into an array
			For Local x% = 0 To w - 1
				For Local y% = 0 To h -1	
					Local argb:Int=ReadPixel(image,x,y)
					array[x,y] = argb
				Next
			Next
			
			' work out the average colour
			For Local x%=0 To w-1
				For Local y% = 0 To h -1	
					Local a% = (array[x,y] Shr 24) & $ff
					If a = 0 ' transparent
						Local r%, g%, b%
						Local no%
						Local pixel%
						
						' above
						If y>0 Then
							pixel% = array[x,y-1]
							If ((pixel Shr 24)& $ff) <> 0 Then
								r = r + (pixel Shr 16)& $ff
								g = g + (pixel Shr 8)& $ff
								b = b + pixel & $ff
								no:+1					
							EndIf
						End If
						
						'below
						If y<h-1 Then
							pixel% = array[x,y+1]
							If ((pixel Shr 24)& $ff) <> 0 Then
								r = r + (pixel Shr 16)& $ff
								g = g + (pixel Shr 8)& $ff
								b = b + pixel & $ff
								no:+1					
							EndIf				
						EndIf
						
						' left			
						If x<w-1 Then
							pixel% = array[x+1,y]
							If ((pixel Shr 24)& $ff) <> 0 Then
								r = r + (pixel Shr 16)& $ff
								g = g + (pixel Shr 8)& $ff
								b = b + pixel & $ff
								no:+1					
							EndIf				
						EndIf
						
						' right
						If x>0 Then
							pixel% = array[x-1,y]
							If ((pixel Shr 24)& $ff) <> 0 Then
								r = r + (pixel Shr 16)& $ff
								g = g + (pixel Shr 8)& $ff
								b = b + pixel & $ff
								no:+1					
							EndIf				
						EndIf
						
						If no > 0
							r = r / no
							g = g / no
							b = b / no
						EndIf
						
						Local argb% =( a Shr 24 )+( r Shl 16 )+( g Shl 8 )+b
			
						array[x,y] = argb
					End If
				Next
			Next
			
			' write the pixel
			For Local x% = 0 To w - 1
				For Local y% = 0 To h -1
					Local argb% = array[x,y]
					WritePixel(Tmp , x , y ,argb)
				Next
			Next
			
			' save the image
			Local file:String=savedir +""+testfile
			Print "Saving.... "+testfile
			If file>"" SavePixmapPNG(Tmp,file, 9)
		EndIf
	EndIf
Forever
CloseDir dir
Print ""
Print "Finished..."
WaitKey


Exe and Code:
http://therevills.syntaxbomb.com/Multi-Defringe/Multi-Defringe.zip

therevills is making me twitch :)

Why don't you just change your name to Captain Pedantic and be done with it?
Coming from Captain GrumpyfK..

It would be more ideal that the graphics softare with which you create your images in the first place, saves the data in the correct manner, separating alpha from pixel values rather than combining them, then you wouldn't have to try to fake a defringe after the fact?

It would be more ideal that the graphics softare with which you create your images in the first place, saves the data in the correct manner


True, but if you are getting someone else to do the graphics, you haven't got much of a choice...

BTW When I was quickly commenting the code, I got the left and right comments back to front... ;-)

Cool! So are you averaging the surrounding 8 pixels or what? How does the algorithm work exactly? I wonder if it's the same as the original and if there are any pitfalls that need to be avoided etc?

So are you averaging the surrounding 8 pixels or what?


I did originally do the surrounding 8 pixels but it worked out better to do just 4 (above, below, right and left)... but if you need that the code is there, just add it eg:

' above & left
						If y>0 and x>0 Then
							pixel% = array[x-1,y-1]
							If ((pixel Shr 24)& $ff) <> 0 Then
								r = r + (pixel Shr 16)& $ff
								g = g + (pixel Shr 8)& $ff
								b = b + pixel & $ff
								no:+1					
							EndIf
						End If						


How does the algorithm work exactly?


It stores the pixels image into an array, then loops thru the array, if any of the pixels are transparent it then checks the 4 pixels above, below, right and left of it, if they are not transparent it stores their colour, once it has got all the colours it averages it and stores it back into the array.

Once its done all the array, it then writes the array back as pixels and saves the png...

This is all wrapped in a read directory loop...

It would be great, if anyone could test it... I converted all my graphics for my next game (200 images) last night with it and it seems to work quite well...

Great, thanks for the detail. I'm glad you used the array system as I was worried that if you altered a pixel straight away that it would affect the average for other nearby pixels. You are too clever for that, I worried needlessly :-)

Can't test now as I'm on laptop in Seattle, but also I'm not sure if I have any non-defringed images any more!