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 |