Simple image processing
Posted: Sat Jan 06, 2007 9:48 pm
Hello,
here are some simple but fairly effective procedures for image manipulation: 180 degrees rotation, 90 degrees rotation, mirror, flip, greyscaling, inversion, image brightness and image contrast. There are probably more elegant ways to implement these things, and certainly more optimized ones (using lookup tables etc)... but maybe someone will have use for these.
Note: The alpha-macros are not used in these procedures but I included them anyway to show one possible way of blending two color values. If you need to blend colors inside an image processing procedure, it is best to use a macro anway. I'll post my noise and matrix filter -procedures later to show how I use them.
here are some simple but fairly effective procedures for image manipulation: 180 degrees rotation, 90 degrees rotation, mirror, flip, greyscaling, inversion, image brightness and image contrast. There are probably more elegant ways to implement these things, and certainly more optimized ones (using lookup tables etc)... but maybe someone will have use for these.
Note: The alpha-macros are not used in these procedures but I included them anyway to show one possible way of blending two color values. If you need to blend colors inside an image processing procedure, it is best to use a macro anway. I'll post my noise and matrix filter -procedures later to show how I use them.
Code: Select all
EnableExplicit
;*********************************************************************
;*
;*
;- MACROS
;*
;*
;{********************************************************************
Macro RGB(Red, Green, Blue)
((Blue << 8 + Green) << 8 ) + Red
EndMacro
Macro Red(Color)
Color & 16777215 >> 16
EndMacro
Macro Green(Color)
(Color & 65535) >> 8
EndMacro
Macro Blue(Color)
Color >> 16
EndMacro
Macro Normalize(Red, Green, Blue)
If Red < 0
Red = 0
ElseIf Red > 255
Red = 255
EndIf
If Green < 0
Green = 0
ElseIf Green > 255
Green = 255
EndIf
If Blue < 0
Blue = 0
ElseIf Blue > 255
Blue = 255
EndIf
EndMacro
;}********************************************************************
;*********************************************************************
;*
;*
;- ALPHA
;*
;*
;{********************************************************************
Macro Blend75(ColorA, Color)
RGB((Red(ColorA) >> 1 + Red(ColorA) >> 2 + Red(ColorO) >> 2), (Green(ColorA) >> 1 + Green(ColorA) >> 2 + Green(ColorO) >> 2), (Blue(ColorA) >> 1 + Blue(ColorA) >> 2 + Blue(ColorO) >> 2))
EndMacro
Macro Blend50(ColorA, ColorO)
RGB((Red(ColorA) >> 1 + Red(ColorO) >> 1), (Green(ColorA) >> 1 + Green(ColorO) >> 1), (Blue(ColorA) >> 1 + Blue(ColorO) >> 1))
EndMacro
Macro Blend(ColorA, ColorO, Alpha)
RGB(((Red(ColorA) * Alpha + Red(ColorO) * (256 - Alpha)) >> 8), ((Green(ColorA) * Alpha + Green(ColorO) * (256 - Alpha)) >> 8), ((Blue(ColorA) * Alpha + Blue(ColorO) * (256 - Alpha)) >> 8))
EndMacro
;}********************************************************************
;*********************************************************************
;*
;*
;- MEMORY
;*
;*
;{********************************************************************
Procedure CopyImageToMemory(ImageNumber, Memory)
Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
TemporaryBitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
TemporaryBitmapInfo\bmiHeader\biWidth = TemporaryBitmap\bmWidth
TemporaryBitmapInfo\bmiHeader\biHeight = -TemporaryBitmap\bmHeight
TemporaryBitmapInfo\bmiHeader\biPlanes = 1
TemporaryBitmapInfo\bmiHeader\biBitCount = 32
TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
DeleteDC_(TemporaryDC)
EndProcedure
Procedure CopyMemoryToImage(Memory, ImageNumber)
Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
TemporaryBitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
TemporaryBitmapInfo\bmiHeader\biWidth = TemporaryBitmap\bmWidth
TemporaryBitmapInfo\bmiHeader\biHeight = -TemporaryBitmap\bmHeight
TemporaryBitmapInfo\bmiHeader\biPlanes = 1
TemporaryBitmapInfo\bmiHeader\biBitCount = 32
TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
DeleteDC_(TemporaryDC)
EndProcedure
;}********************************************************************
;*********************************************************************
;*
;*
;- ROTATION
;*
;*
;{********************************************************************
Procedure Rotate180(ImageNumber)
Protected MemorySize, *MemoryOrigin, *MemoryTarget, Counter
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*MemoryOrigin = AllocateMemory(MemorySize)
*MemoryTarget = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *MemoryOrigin)
For Counter = 0 To MemorySize - 1 Step 4
PokeL(*MemoryTarget + MemorySize - Counter - 4, PeekL(*MemoryOrigin + Counter))
Next
CopyMemoryToImage(*MemoryTarget, ImageNumber)
FreeMemory(*MemoryOrigin)
FreeMemory(*MemoryTarget)
EndProcedure
Procedure Rotate90(ImageNumber)
Protected TemporaryImage, MemorySizeOrigin, MemorySizeTarget, *MemoryOrigin, *MemoryTarget
Protected Origin, Target, W, H, X, Y
TemporaryImage = CreateImage(#PB_Any, ImageHeight(ImageNumber), ImageWidth(ImageNumber), ImageDepth(ImageNumber))
MemorySizeOrigin = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
MemorySizeTarget = (ImageWidth(TemporaryImage) * ImageHeight(TemporaryImage) << 2)
*MemoryOrigin = AllocateMemory(MemorySizeOrigin)
*MemoryTarget = AllocateMemory(MemorySizeTarget)
CopyImageToMemory(ImageNumber, *MemoryOrigin)
W = ImageWidth(ImageNumber)
H = ImageHeight(ImageNumber)
For Y = 0 To H - 1
For X = 0 To W - 1
Origin = (Y * W + X) << 2
Target = ((H - Y - 1) + (X * H)) << 2
PokeL(*MemoryTarget + Target, PeekL(*MemoryOrigin + Origin))
Next
Next
CopyMemoryToImage(*MemoryTarget, TemporaryImage)
FreeImage(ImageNumber)
CopyImage(TemporaryImage, ImageNumber)
FreeImage(TemporaryImage)
FreeMemory(*MemoryOrigin)
FreeMemory(*MemoryTarget)
EndProcedure
Procedure Mirror(ImageNumber)
Protected MemorySize, *MemoryOrigin, *MemoryTarget
Protected Origin, Target, W, H, X, Y
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*MemoryOrigin = AllocateMemory(MemorySize)
*MemoryTarget = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *MemoryOrigin)
W = ImageWidth(ImageNumber)
H = ImageHeight(ImageNumber)
For Y = 0 To H - 1
For X = 0 To W - 1
Origin = (Y * W + X) << 2
Target = ((W - X) + (Y * W - 1)) << 2
PokeL(*MemoryTarget + Target, PeekL(*MemoryOrigin + Origin))
Next
Next
CopyMemoryToImage(*MemoryTarget, ImageNumber)
FreeMemory(*MemoryOrigin)
FreeMemory(*MemoryTarget)
EndProcedure
Procedure Flip(ImageNumber)
Protected MemorySize, *MemoryOrigin, *MemoryTarget
Protected Origin, Target, W, H, X, Y
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*MemoryOrigin = AllocateMemory(MemorySize)
*MemoryTarget = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *MemoryOrigin)
W = ImageWidth(ImageNumber)
H = ImageHeight(ImageNumber)
For Y = 0 To H - 1
For X = 0 To W - 1
Origin = (Y * W + X) << 2
Target = ((H - Y - 1) * W + X) << 2
PokeL(*MemoryTarget + Target, PeekL(*MemoryOrigin + Origin))
Next
Next
CopyMemoryToImage(*MemoryTarget, ImageNumber)
FreeMemory(*MemoryOrigin)
FreeMemory(*MemoryTarget)
EndProcedure
;}********************************************************************
;*********************************************************************
;*
;*
;- COLOR
;*
;*
;{********************************************************************
Procedure Greyscale(ImageNumber)
Protected MemorySize, *Memory
Protected Counter, Color
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*Memory = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *Memory)
For Counter = 0 To MemorySize - 1 Step 4
Color = PeekL(*Memory + Counter)
Color = (Red(Color) + Green(Color) + Blue(Color)) / 3
PokeL(*Memory + Counter, RGB(Color, Color, Color))
Next
CopyMemoryToImage(*Memory, ImageNumber)
FreeMemory(*Memory)
EndProcedure
Procedure Invert(ImageNumber)
Protected MemorySize, *Memory
Protected Counter, Color, Red, Green, Blue
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*Memory = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *Memory)
For Counter = 0 To MemorySize - 1 Step 4
Color = PeekL(*Memory + Counter)
Red = 255 - Red(Color)
Green = 255 - Green(Color)
Blue = 255 - Blue(Color)
PokeL(*Memory + Counter, RGB(Red, Green, Blue))
Next
CopyMemoryToImage(*Memory, ImageNumber)
FreeMemory(*Memory)
EndProcedure
Procedure Brightness(ImageNumber, Brightness)
Protected MemorySize, *Memory
Protected Counter, Color, Red, Green, Blue
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*Memory = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *Memory)
For Counter = 0 To MemorySize - 1 Step 4
Color = PeekL(*Memory + Counter)
Red = Red(Color) + Brightness
Green = Green(Color) + Brightness
Blue = Blue(Color) + Brightness
Normalize(Red, Green, Blue)
PokeL(*Memory + Counter, RGB(Red, Green, Blue))
Next
CopyMemoryToImage(*Memory, ImageNumber)
FreeMemory(*Memory)
EndProcedure
Procedure Contrast(ImageNumber, Contrast.F)
Protected MemorySize, *Memory
Protected Counter, Color, Red, Green, Blue
MemorySize = (ImageWidth(ImageNumber) * ImageHeight(ImageNumber) << 2)
*Memory = AllocateMemory(MemorySize)
CopyImageToMemory(ImageNumber, *Memory)
For Counter = 0 To MemorySize - 1 Step 4
Color = PeekL(*Memory + Counter)
Red = ((Red(Color) - 128) * Contrast) + 128
Green = ((Green(Color) - 128) * Contrast) + 128
Blue = ((Blue(Color) - 128) * Contrast) + 128
Normalize(Red, Green, Blue)
PokeL(*Memory + Counter, RGB(Red, Green, Blue))
Next
CopyMemoryToImage(*Memory, ImageNumber)
FreeMemory(*Memory)
EndProcedure
;}********************************************************************