Create a grayscaled image on the fly?
BlitzMax Forums/BlitzMax Beginners Area/Create a grayscaled image on the fly?
| ||
Hi! Has someone written a function that grayscales an existing image file handle? Grisu |
| ||
Tested once, looked ok. Didn't verify anything tho :P SuperStrict Local window:TGadget=CreateWindow("o_O",0,0,640,480) Local canvas:TGadget=CreateCanvas(0,0,640,480,window) Local img:TImage=LoadImage("Porn193882.JPG") MakeGrey img SetGraphics CanvasGraphics(canvas) Cls DrawImage img,0,0 Flip Notify "o_O" End Function MakeGrey(img:TImage) If img=Null RuntimeError "no image!" Local c:Int Local x:Int Local y:Int Local pm:TPixmap=LockImage(img) For y=0 Until ImageHeight(img) For x=0 Until ImageWidth(img) c= ReadPixel(pm,x,y) & 255 c:+(ReadPixel(pm,x,y) Shr 8) & 255 c:+(ReadPixel(pm,x,y) Shr 16) & 255 c:/3 WritePixel pm,x,y,$ff000000|c+256*c+65536*c Next Next UnlockImage img End Function |
| ||
Has someone written a function that grayscales an existing image file handle? Yes, Birdie has. Check the FilmClip sample that's distributed along with BlitzMAX. It's in /samples/birdie/misc/filmclip/. |
| ||
grmbl, that birdie-example just froze my system pretty hard.. |
| ||
Thanks everyone! My guess is Birdies code is faster as it only uses ONE readpixel a time! edit: The code works fine and IS A LOT FASTER! Function ConvertToBW(i:TImage,frame) Local col,a,r,g,b,cc,x=0,y=0 Local pix:TPixmap pix=LockImage(i,frame) While y<i.height x=0 While x<i.width col = ReadPixel( pix, x, y ) a = ( col & $ff000000) r = ( col & $ff0000 ) Shr 16 g = ( col & $ff00 ) Shr 8 b = ( col & $ff ) cc= (r+g+b)/3 col = a | (cc Shl 16) | (cc Shl 8) | cc WritePixel( pix, x, y, col ) x=x+1 Wend y=y+1 Wend UnlockImage i,frame EndFunction |
| ||
uh yeah.. st00pid me.. ^_^ |
| ||
Some ideas on how you can make that faster: Get rid of having to store all the components in separate variables, and also get rid of putting the combined components into the col variable - just do the combining in the WritePixel. Get rid of the ReadPixel and the WritePixel because they each require a calculation (that includes a multiply) to work out where in memory to read/write the pixel data. Just use an Int Ptr pointing to the base address of the pixmap memory, and make sure to add any additional pitch to the end of each row. Then use address[x] to read/write the data, and add width in pixels at the end of each row to skip to the next row. Take out the i.height and i.width, put them in local variables outside the loops and call the local variables. Local pix:TPixmap can be just Local pix:TPixmap=LockImage(i,frame) It's not necessarily faster to use a While/Wend than to use a For-Next - you are only doing manually what a for-next loop would do automatically Try and find a way to get rid of the /3 Anyway, that aside, you shouldn't have to do this `offline` away from video memory, you can probably get your image to render in grayscale using some blend mode of the graphics card hardware. |
| ||
This one is faster, but now the image is all dark blue... :(Function ConvertBW(i:TImage) Local w,h,col,a,r,g,b,cc,x=0,y=0 Local pix:TPixmap=LockImage(i) h= i.height w= i.width While y < h x=0 While x < w col = ReadPixel( pix, x, y ) col = ( col & $ff000000) | ((col & $ff0000) Shl 16) | ((col & $ff00) Shl 8) | (col & $ff) WritePixel( pix, x, y, col ) x=x+1 Wend y=y+1 Wend UnlockImage i EndFunction |
| ||
You guys are going about it all the wrong way : http://www.blitzbasic.com/Community/posts.php?topic=56099 |
| ||
This one is faster, but now the image is all dark blue... :( Because you forgot something col = ( col & $ff000000) | ( ((col & $ff0000) Shr 16) + ((col & $ff00) Shr 8) + (col & $ff) )/3 * 65793 and what about it?. create a pixmap image with format ' PF_I8 - 8 bit intensity' Graphics 640,480,0 Local full:TPixmap=LoadPixmap("IMAGEN.jpg") Local gray:TPixmap=CreatePixmap(PixmapWidth(full),PixmapHeight(full),PF_I8,1) For Local y:Int=0 To PixmapHeight(full)-1 For Local x:Int=0 To PixmapWidth(full)-1 WritePixel( gray, x, y, ReadPixel( full, x, y ) ) Next Next DrawPixmap gray,100,100 Flip WaitKey() or........! Graphics 640,480,0 Local full:TPixmap=LoadPixmap("IMAGEN.jpg") Local gray:TPixmap gray=full.Convert(PF_I8) DrawPixmap gray,100,100 Flip WaitKey() |
| ||
Thanks for the code BlackSp1der! Seems as fast as it can get... :) |