TGC Codebase Backup



Merge Image (Now 30% Faster) by Mage

3rd Feb 2007 22:50
Summary

Merges one image onto another image, making use of the top images transparency to produce a layered effect. Useful for clothed body textures where skin tone varies.



Description

Merges one image onto another image, making use of the top images transparency to produce a layered effect.

I borrowed code a year ago from someone off the forum that loads an image to a memblock. (I can't remember who! Tell Me!)

I hacked the code to merge two images and place the result over the original image. This was done because I needed my player model to have layered clothing textures to reduce the needed image files.

**NEW
Now works with images that differ in size.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    function Media_MergeImage(MyImage, MergeImage)
   If MyImage < 1 then ExitFunction
   If Image Exist(MyImage) = 0 then ExitFunction
   If MergeImage < 1 then ExitFunction
   If Image Exist(MergeImage) = 0 then ExitFunction


   `Find unused memblocks
   Memblock1 = 1
   repeat
      inc Memblock1
   until memblock exist(Memblock1) = 0
   Memblock2 = 2
   repeat
      inc Memblock2
   until memblock exist(Memblock2) = 0

  `Set up variables
   Width as Dword
   Height as Dword
   Depth as Dword
   Red as Byte
   Green as Byte
   Blue as Byte
   Alpha as Byte

   `Do it!
   make memblock from image Memblock1, MyImage
   Width = memblock dword(Memblock1,0)
   Height = memblock dword(Memblock1,4)
   Depth = memblock dword(Memblock1,8)
   make memblock from image Memblock2, MergeImage
   Width2 = memblock dword(Memblock2,0)
   Height2 = memblock dword(Memblock2,4)

   If Width = 0 then ExitFunction
   If Width2 = 0 then ExitFunction
   If Height = 0 then ExitFunction
   If Height2 = 0 then ExitFunction

   w1# = Width
   w2# = Width2
   h1# = Height
   h2# = Height2

   xMod# = w2# / w1#
   yMod# = h2# / h1#

   `Perform Overlay, optimize operations if images are same size
   Position = 12 `skip header
   mCounter = 1
   If xMod# = 1 and yMod# = 1
   for y = 1 to Height `Height
      for x = 1 to Width`Width
            Alpha = memblock byte(Memblock1, Position+3)
            Blue = memblock byte(Memblock1,Position)
            Green = memblock byte(Memblock1,Position+1)
            Red = memblock byte(Memblock1,Position+2)

            oAlpha = memblock byte(Memblock2, Position+3)
            oBlue = memblock byte(Memblock2,Position)
            oGreen = memblock byte(Memblock2,Position+1)
            oRed = memblock byte(Memblock2,Position+2)

            If oAlpha > 0
               Blue = Blue + ((oAlpha * (oBlue - Blue)) / 255.0)
               Green = Green + ((oAlpha * (oGreen - Green)) / 255.0)
               Red = Red + ((oAlpha * (oRed - Red)) / 255.0)
               Alpha = Alpha + oAlpha
            EndIf

            newCol = (Alpha << 24) + (Red << 16) + (Green << 8) + Blue `//argb
            write memblock Dword Memblock1,Position, newCol
            inc Position,4
       next x
   next y
   Else
   for y = 1 to Height `Height
      for x = 1 to Width`Width
            xPos = (x * xMod#)
            yPos = (y * yMod#)

            mPosition = (((yPos - 1) * Width2) * 4) + ((xPos - 1) * 4) + 12
            Alpha = memblock byte(Memblock1, Position+3)
            Blue = memblock byte(Memblock1,Position)
            Green = memblock byte(Memblock1,Position+1)
            Red = memblock byte(Memblock1,Position+2)

            oAlpha = memblock byte(Memblock2, mPosition+3)
            oBlue = memblock byte(Memblock2,mPosition)
            oGreen = memblock byte(Memblock2,mPosition+1)
            oRed = memblock byte(Memblock2,mPosition+2)

            If oAlpha > 0
               Blue = Blue + ((oAlpha * (oBlue - Blue)) / 255.0)
               Green = Green + ((oAlpha * (oGreen - Green)) / 255.0)
               Red = Red + ((oAlpha * (oRed - Red)) / 255.0)
               Alpha = Alpha + oAlpha
            EndIf

            newCol = (Alpha << 24) + (Red << 16) + (Green << 8) + Blue `//argb
            write memblock Dword Memblock1,Position, newCol
            inc Position,4
      next x
   next y
   EndIf
   make image from memblock MyImage,Memblock1
   delete memblock Memblock1
   delete memblock Memblock2
endfunction