Savesprite transparency problem

Previous topic - Next topic

Crivens

I've written a small routine to automatically load iOS retina sized graphics and resize to the screen size you are actually using (eg. 3GS res). It then saves these using savesprite to a png file so next time it will load faster (and more importantly use less memory) on the non-retina devices (using a version file). This nicely works apart from one thing. Basically anything with transparency I have as pink (255,0,128) and even make sure it is set to pink just incase at the start of the routine. I then fill the screen with pink to make sure if the transparency channel of the png is being used rather than pink then it will make those pixels pink (forget partial transparency for now, even if GLB supports it). I then paste it resized, use grabsprite, and then savesprite.

All this works very well. I have no issues. Apart from transparency. I have a png file that resizes correctly, and keeps the pink that was in the original as pink. They are exactly the same except the resized one is 4 times smaller obviously. However using the resized sprite keeps the pink on the screen, whereas the original is transparent. Interestingly using Paint Shop Pro 8 if I load the resized sprite and then immediately save over itself, then GLB shows the pink as transparent, which leads me to believe that possibly the savesprite command doesn't work correctly with the transparent channel.

I've included the 3 files for comparison. Basically retina.png is the original large sprite. resized.png is what GLB automatically created (on a PC, I haven't tried yet on iOS) which shows transparent instead of pink. And psp8.png is the same resized.png that I just loaded into psp8, saved immediately, and then ran the exact same GLB code again to find it worked with transparency.

Cheers



[attachment deleted by admin]
Current fave quote: Cause you like musicians and I like people with boobs.

Crivens

Interestingly this works perfectly fine on the iPhone 3GS. The shrunken saved file has perfectly fine transparency. No worries really then as I test on the PC at full retina resolution anyway. And for testing I can PSP8 the converted ones. So put this down as a low priority. Might be important for someone else though developing on the PC.

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

Crivens

#2
And incase anyone is interested in the routine, here is my test code that loads images and resizes them if required (if a version text file has a different content), putting them into a separate directory (auto created in documents). It also contains simple code to use the correct resolution.

Code (glbasic) Select
TYPE tMouse
x%
y%
active%
ENDTYPE
GLOBAL mouse[] AS tMouse
DIM mouse[5]
SYSTEMPOINTER TRUE

GLOBAL screenx,screeny
GLOBAL myx,myy,x,y
GOSUB screeninit
LOCAL spr1=GENSPRITE()
LOADSPRITE "A0000001.png",spr1
LOCAL spx,spy
GETSPRITESIZE spr1,spx,spy
LOCAL spr2=GENSPRITE()
LOADSPRITE "A0000002.png",spr2
LOADBMP "A0000001.png"
LOCAL text$="X="+myx+" Y="+myy
LOCAL spr1x,spr1y,spr1w,spr1h,spr2x,spr2y,spr2w,spr2h
spr1w=(spx/5)/x;spr1h=(spy/5)/y;spr1x=spr1w;spr1y=screeny-spr1h
spr2w=spr1w;spr2h=spr1h;spr2x=screenx-spr2w*2;spr2y=spr1y
LOCAL button=GENSPRITE()
LOADSPRITE "A0000003.png",button
WHILE 1=1
STRETCHSPRITE spr1,spr1x*x,spr1y*y,spr1w*x,spr1h*y
STRETCHSPRITE spr2,spr2x*x,spr2y*y,spr2w*x,spr2h*y
DRAWSPRITE button,100*x,400*y //Just to test transparent sprite
PRINT text$,100*x,100*y //Not resized font yet!
updateMice()
IF mouse[0].active=1
IF mouse[0].x>=spr1x AND mouse[0].x<=spr1x+spr1w AND mouse[0].y>=spr1y AND mouse[0].y<=spr1y+spr1h
LOADBMP "A0000001.png"
ELSEIF mouse[0].x>=spr2x AND mouse[0].x<=spr2x+spr2w AND mouse[0].y>=spr2y AND mouse[0].y<=spr2y+spr2h
LOADBMP "A0000002.png"
ENDIF
ENDIF
SHOWSCREEN
WEND

FUNCTION debug_out: in$
LOCAL out$
out$="[APP] "+MID$(PLATFORMINFO$("TIME"),11,8) + ": "+ in$+"\n"
?IFDEF IPHONE
STDOUT out$
?ELSE
DEBUG out$
?ENDIF
ENDFUNCTION

FUNCTION updateMice:
LOCAL imouse%,mx%, my%, b1%, b2%
FOR imouse% = 0 TO MIN(GETMOUSECOUNT()-1,4)
SETACTIVEMOUSE imouse%
MOUSESTATE mx%, my%, b1%, b2%
mouse[imouse].x=mx/x
mouse[imouse].y=my/y
mouse[imouse].active=b1
NEXT
ENDFUNCTION

SUB screeninit: //Initialises the screen for devices
screenx=640;screeny=960 //Highest resolution supported
?IFNDEF IPHONE
SETSCREEN screenx,screeny,0
?ENDIF
GETSCREENSIZE myx,myy
x=myx/screenx;y=myy/screeny //Work out ratio
GOSUB resizepics
ENDSUB

SUB resizepics: //Takes all pictures available and turns them into the right size (A9999999.png)
SMOOTHSHADING FALSE
SETTRANSPARENCY RGB(255,0,128) //Just incase it isn't pink!
SETCURRENTDIR("Media") // seperate media and binaries
IF x<>1 AND y<>1 //Need to resize all images
LOCAL docdir$=PLATFORMINFO$("DOCUMENTS")+"/Lovetronbin" //Has to be different for iPhone
CREATEDIR(docdir$)
LOCAL needresize=1
IF DOESFILEEXIST(docdir$+"/ver.txt") //Must exist in target directory
IF DOESFILEEXIST("ver.txt") //And in media directory
LOCAL file1=GENFILE()
OPENFILE(file1,docdir$+"/ver.txt",TRUE)
LOCAL file2=GENFILE()
OPENFILE(file2,"ver.txt",TRUE)
LOCAL file1line$,file2line$
READLINE file1,file1line$
READLINE file2,file2line$
IF file1line$=file2line$ THEN needresize=0
CLOSEFILE file1
CLOSEFILE file2
ENDIF
ENDIF
IF needresize=1
LOCAL files$[]
LOCAL i
LOCAL mysprite
CLEARSCREEN
mysprite=GENSPRITE()
GETFILELIST("A???????.png", files$[])
LOCAL lpx,lpy
FOR i=0 TO BOUNDS(files$[], 0)-1
IF INSTR(UCASE$(files$[i]),".PNG")>0
//PRINT files$[i],0,i*10
DRAWRECT 0,0,myx,myy,RGB(255,0,128) //Default the pink
LOADSPRITE files$[i],mysprite
GETSPRITESIZE mysprite,lpx,lpy
STRETCHSPRITE mysprite,0,0,lpx*x,lpy*y
GRABSPRITE mysprite,0,0,lpx*x,lpy*y
SAVESPRITE docdir$+"/"+files$[i],mysprite 
ENDIF
NEXT
LOADSPRITE "",mysprite //Clear memory
COPYFILE "ver.txt",docdir$+"/ver.txt"
ENDIF
SETCURRENTDIR(docdir$)
ENDIF
ENDSUB


Note to change it to pre iPhone 4 resolutions (or any other really) for your PC then use SETSCREEN screenx/2,screeny/2,0 instead of what is there currently (SETSCREEN screenx,screeny,0). Obviously you would need to update the ver.txt file though so it knows to resize everything again, but it's really designed for iOS and not PCs that can be any resolution you want. I've attached screenshots to give the idea what it does (touch thumbnails at bottom to refresh background with non-functional orange button).

Cheers

[attachment deleted by admin]
Current fave quote: Cause you like musicians and I like people with boobs.

Ian Price

IIRC this came up before - I can't remember what the solution was though, but I suspect you've hit the nail on the head with transparency info not being saved correctly. Odd that it's on one system and not another though.

Have you tried using POLYVECTOR/ZOOMSPRITE/STRETCHSPRITE to scale the button instead? Seems like a lot of effort to do the same thing in code that already exists as part of the commandset. However, sometimes it's good to experiment with alternatives.  :)

BTW Those are really nice buttons Crivens, how did you create them? Any chance of a quick tut?
I came. I saw. I played.

Crivens

#4
I use stretchsprite. If you look in the posted code you can see exactly how I do it. Pretty simple really. I would bet it's the png library for windows being different to iOS. The file sizes are a lot better on iOS too.

The button? Think I got it from standard stuff in psp8. Either that or an icon app I bought years ago. Can't remember which, but the icon app is awesome at mixing images. Out of interest does GLB support partially transparent sprites (is it called alphablended sprites?)? This app is brilliant at icons but is nowhere near as good unless you can use the full different levels of transparency as I remember years ago with VB6 and .net. Would throw my resize function out the window though unless a savesprite command with percentage and full transparency can be done.

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.