Code archives/Graphics/Shadow from an image
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This function creates a shadow an image, by reading the "red" value and setting it to all three rgb values, amking a grey. its reasonably fast aswell. | |||||
Function GenerateShadow(img, r = 255, g = 0, b = 255) setbuffer imagebuffer(img) lockbuffer for x = 0 to imagewidth(img) - 1 for y = 0 to imageheight(img) - 1 col = readpixelfast (x, y) color 0, 0, col if not (colorred() = r and colorgreen() = g and colorblue() = 255) color colorred(), colorred(), colorred() plot x, y endif next next unlockbuffer setbuffer backbuffer() return img end function |
Comments
| ||
Hmmm... it doesn't work on BlitzPlus. First: you are writing on the img, it is better to create a copy. Second: you should set the buffer back to the original Buffer, not to BackBuffer(). Third: you can't use Plot on a locked buffer, you must unlock it first. ; SHADOW GENERATOR, the mask color is not affected Function GenerateShadow(sourceImg, r = 0, g = 0, b =0) img=CopyImage(sourceImg) originalBuffer=GraphicsBuffer() SetBuffer ImageBuffer(img) LockBuffer For x = 0 To ImageWidth(img) - 1 For y = 0 To ImageHeight(img) - 1 col = ReadPixelFast (x, y) ; convert to rgb values r1=(col Shl 8)Shr 24 g1=(col Shl 16)Shr 24 b1=(col Shl 24)Shr 24 If Not (r1 = r And g1 = g And b1 = b) UnlockBuffer Color r1,r1,r1 Plot x,y ;WritePixelFast x,y,calculatenewcolor LockBuffer EndIf Next Next UnlockBuffer SetBuffer originalBuffer Return img End Function Use WritePixelFast would be much better than Plot of course, just let me find some time to code it. This is more a grayscale converter than a real shadow... but it is easier to convert it into a shadow, you must use always the same r g b gray value instead of converting each rgb color to a different grayscale level. |
| ||
Here is the final version of the functions: GenerateShadow() for genearting a shadow with a unique gray color, and GenerateGrayScale() for a grayscale version of the orignal image There is also a small example to test it, just change the path and maskcolor of your image (I tried with a red maskcolor). Graphics 640,480,16,2 SetBuffer BackBuffer() myImage=LoadImage("gfx\zelda1.bmp") MaskImage myImage,255,0,0 myShadow=GenerateShadow(myImage,255,0,0,80) myGrayScale=GenerateGrayScale(myImage,255,0,0) While KeyDown(1)=0 Cls DrawImage myShadow,MouseX(),MouseY() DrawImage myGrayScale,MouseX()-100,MouseY()-100 DrawImage myImage,0,0 Flip Wend End ; SHADOW GENERATOR, the mask color is not affected ; coded by Roberto Comuniello, 2004, www.sintetik.it ; sourceImg: source Image handle ; r: red mask color ; g: green mask color ; b: blue mask color ; shadowLevel: intensity of shadow (grey color) from 0 to 255 Function GenerateShadow(sourceImg, r = 0, g = 0, b =0, shadowLevel=100) img=CopyImage(sourceImg) myWidth=ImageWidth(img)-1 myHeight=ImageHeight(img)-1 myMask=GetRGB(r,g,b) myShadow=GetRGB(shadowLevel,shadowLevel,shadowLevel) originalBuffer=GraphicsBuffer() SetBuffer ImageBuffer(img) LockBuffer For x = 0 To myWidth For y = 0 To myHeight col = ReadPixelFast (x, y) If Not (col=myMask) WritePixelFast x,y,myShadow EndIf Next Next UnlockBuffer SetBuffer originalBuffer Return img End Function ; GRAYSCALE GENERATOR, the mask color is not affected ; the grayscale is based on the red color of each pixels ; coded by Roberto Comuniello, 2004, www.sintetik.it ; it works fine even if you have a red mask (255,0,0) ; sourceImg: source Image handle ; r: red mask color ; g: green mask color ; b: blue mask color Function GenerateGrayScale(sourceImg, r = 0, g = 0, b =0) img=CopyImage(sourceImg) myWidth=ImageWidth(img)-1 myHeight=ImageHeight(img)-1 myMask=GetRGB(r,g,b) originalBuffer=GraphicsBuffer() SetBuffer ImageBuffer(img) LockBuffer For x = 0 To myWidth For y = 0 To myHeight col = ReadPixelFast (x, y) If Not (col=myMask) r1=GetR(col) myNewColor=GetRGB(r1,r1,r1) WritePixelFast x,y,myNewColor EndIf Next Next UnlockBuffer SetBuffer originalBuffer Return img End Function ; general purpose RGB converter functions Function GetRGB(R,G,B) Return $FF000000 Or R Shl 16 Or G Shl 8 Or B End Function Function GetR(RGB) Return RGB Shr 16 And %11111111 End Function Function GetG(RGB) Return RGB Shr 8 And %11111111 End Function Function GetB(RGB) Return RGB And %11111111 End Function |
| ||
Here is the final version, with shadow transparency as an option! Simple and quite good to see. Just try it with a tiled background as I did. Maybe it should be optimized but it is already quite good. Graphics 640,480,16,2 SetBuffer BackBuffer() myImage=LoadImage("gfx\zelda1.bmp") MaskImage myImage,255,0,0 myShadow=GenerateShadow(myImage,255,0,0,80,1) myGrayScale=GenerateGrayScale(myImage,255,0,0) myTile=LoadImage("gfx\tile.bmp") While KeyDown(1)=0 TileBlock myTile DrawImage myShadow,MouseX(),MouseY() DrawImage myGrayScale,MouseX()-100,MouseY()-100 DrawImage myImage,0,0 Flip Wend End ; SHADOW GENERATOR, the mask color is not affected ; coded by Roberto Comuniello, 2004, www.sintetik.it ; sourceImg: source Image handle ; r: red mask color ; g: green mask color ; b: blue mask color ; shadowLevel: intensity of shadow (grey color) from 0 to 255 ; transparent flag: true or false (a fake, cheap transparency effect made with mask color) Function GenerateShadow(sourceImg, r = 0, g = 0, b =0, shadowLevel=100, transparent=False) img=CopyImage(sourceImg) myWidth=ImageWidth(img)-1 myHeight=ImageHeight(img)-1 myMask=GetRGB(r,g,b) myShadow=GetRGB(shadowLevel,shadowLevel,shadowLevel) originalBuffer=GraphicsBuffer() SetBuffer ImageBuffer(img) LockBuffer flipper=False For x = 0 To myWidth flipper=Not flipper For y = 0 To myHeight col = ReadPixelFast (x, y) If Not (col=myMask) Then If flipper Then myCondition=(y Mod 2) Else myCondition=(Not(y Mod 2)) End If If transparent And myCondition Then theShadow=myMask Else theShadow=myShadow End If WritePixelFast x,y,theShadow EndIf Next Next UnlockBuffer SetBuffer originalBuffer Return img End Function ; GRAYSCALE GENERATOR, the mask color is not affected ; the grayscale is based on the red color of each pixel ; coded by Roberto Comuniello, 2004, www.sintetik.it ; it works fine even if you have a red mask (255,0,0) ; sourceImg: source Image handle ; r: red mask color ; g: green mask color ; b: blue mask color Function GenerateGrayScale(sourceImg, r = 0, g = 0, b =0) img=CopyImage(sourceImg) myWidth=ImageWidth(img)-1 myHeight=ImageHeight(img)-1 myMask=GetRGB(r,g,b) originalBuffer=GraphicsBuffer() SetBuffer ImageBuffer(img) LockBuffer For x = 0 To myWidth For y = 0 To myHeight col = ReadPixelFast (x, y) If Not (col=myMask) r1=GetR(col) myNewColor=GetRGB(r1,r1,r1) WritePixelFast x,y,myNewColor EndIf Next Next UnlockBuffer SetBuffer originalBuffer Return img End Function ; general purpose RGB converter functions Function GetRGB(R,G,B) Return $FF000000 Or R Shl 16 Or G Shl 8 Or B End Function Function GetR(RGB) Return RGB Shr 16 And %11111111 End Function Function GetG(RGB) Return RGB Shr 8 And %11111111 End Function Function GetB(RGB) Return RGB And %11111111 End Function |
| ||
wtf was i thinking using plot?! this was quite a whiel ago mind, and must of the comments in the first post would never have occoured :P thanks for the alpha shadow one (i had a function like that but never uploaded it :D) Should be useful to everyone else i think |
Code Archives Forum