MultiplyImage Function
Monkey Forums/Monkey Code/MultiplyImage Function
| ||
This code was re-factored from inside my current project where it generates colored versions of bitmap font images to avoid the SetColor DrawImage penalty in html5. [edit] tested and fixed code x 2 [edit2] changed white pass to to additive ' processimage.monkey ' ' the beginnings of an image processing toolkit for monkey ' ' images can ONLY be processed ' once they are fully loaded ' from inside an OnRender handler ' ' a Cls command should be used after processing any images Strict Import mojo Function Main%() New TestProcess() Return 0 End Class TestProcess Extends App Field font:Image Field redfont:Image Method OnCreate%() font=LoadImage("motorwerk.png") Return 0 End Method OnRender%() If Not redfont redfont=MultiplyImage(font,$ff0000) Endif Cls DrawImage redfont,0,0 Return 0 End End Function MultiplyImage:Image( image:Image,rgb% ) Return ProcessImage( image,New MultiplyPixel(rgb) ) End Interface PixelProcessor Method ProcessPixel%( argb% ) End Class MultiplyPixel Implements PixelProcessor Field factor% Method New(rgb%) factor=rgb End Method ProcessPixel%(argb%) Local a24%=argb & $ff000000 Local r16%=((((argb Shr 16)&$FF)*((factor Shr 16)&$FF))Shr 8)Shl 16 Local g8%=((((argb Shr 8)&$FF)*((factor Shr 8)&$FF))Shr 8)Shl 8 Local b0%=((((argb)&$FF)*((factor)&$FF))Shr 8) Return a24|r16|g8|b0 End End ' batch convert image by reading display size tiles of pixels ' does two pass, white is for color and black is for mask ' write result of callback processing to black ' return result in new image Function ProcessImage:Image(image:Image,pixelproc:PixelProcessor) Local width%=image.Width() Local height%=image.Height() Local stepw%=DeviceWidth() Local steph%=DeviceHeight() If stepw>width stepw=width If steph>height steph=height Local black:=New Int[width*height] Local white:=New Int[width*height] Local x%=0 Local y%=0 While y<height Local h%=height-y If h>steph h=steph While x<width Local w%=width-x If w>stepw w=stepw Cls 255,255,255 SetColor 0,0,0 DrawImage image,-x,-y ReadPixels(black,0,0,w,h,y*width+x,width) Cls 0,0,0 SetBlend AdditiveBlend SetColor 255,255,255 DrawImage image,-x,-y SetBlend AlphaBlend ReadPixels(white,0,0,w,h,y*width+x,width) x+=stepw Wend y+=steph x=0 Wend Local n%=width*height For Local i%=0 Until n Local a%=255-(black[i] & $ff) Local rgb%=white[i] & $ffffff Local rgba%=(a Shl 24) | rgb black[i]=pixelproc.ProcessPixel(rgba) Next Local mult:=CreateImage(width,height) mult.WritePixels black,0,0,width,height Return mult End |
| ||
not bad! To note, this still has all the same limitations that come with ReadPixels (no alpha), plus a small penalty for producing the bitmap, of course. IIRC, Android has some slowness with colored images too, so baking a bitmap there could also be beneficial. In the case of Android, since it's an ogl target, you can also replace readpixels with GetImageData from gles11 and regain the alpha support. |
| ||
It uses white black sampling which should solve the alpha problem. Actually there is possibly a problem with the rgb which my recent change to additive has probably not solved. It's likely I need extra code as my ARGB input is I think now pre-multiplied alpha (darker the more transparent the src). Monkey should probably if it's not already be using pre-multiplied pixel format internally as it is best practice on a lot of EGL chipsets but the Read and Write pixel commands should logically be using plain ARGB so version 3 here we go... TBC |