|
|
||
|
Compositing OperationsCreate sophisticated blended displays using images with alpha.
There are various ways of combining two images together, particularly when either or both of the two images contain alpha channels. As the real-time video-effects industry has developed, twelve standard compositing techniques, know as the Porter-Duff Compositing Operations, have emerged. In addition, many image processing application support other useful operations, such as "Burn" and "Hard-Light". GDI and GDI+ provide very limited support for compositing operations, so this article demonstrates how to perform them using VB code. About CompositingA compositing operation refers to the way in which the pixels from one image, known as the source, are combined with another, known as the destination to produce the final result. Any compositing operation can be described in terms of the source and destination pixel colours and alpha values. The following section describes the 24 operations which are demonstrated in the download code. The following key is used:
Sc - The source element color value.
Sa - The source element alpha value.
Dc - The canvas color value prior to compositing.
Da - The canvas alpha value prior to compositing.
Dc' - The canvas color value post compositing.
Da' - The canvas alpha value post compositing.
All colours must be pre-multiplied by their alpha value prior to performing the calculations, and the equations are shown with colour and alpha values normalized between 0 and 1. In reality, the values run from 0 to 255, and therefore (for example) (1 - Sa) would actually be ((255 - Sa)/255). Finally, although colour values are represented using a single symbol (Sc, Dc or Dc') each colour actually consists of three independent R,G,B components and the calculation needs to be performed individually for each component. Note: The source of this information was the W3C SVG draft specification. Porter-Duff Compositing Operations
Extended Compositing OperationsNote that the colour and alpha values in the extended operations need to be clamped to ensure they don't exceed the 0-255 value range.
Compositing Support in GDI and GDI+The only support for compositing which takes into account the alpha channel in GDI is the AlphaBlend function. Provided the source image is 32 bits/pixel, then setting the BLENDFUNCTION parameter AlphaFormat member set to AC_SRC_ALPHA performs the src_over compositing method. GDI+ provides a CompositingMode setting which determines how two images are combined. The available compositing options are CompositingModeSourceCopy and CompositingModeSourceOver. Implementing the Compositing OperationsIn order to implement these algorithms, two things are needed:
An Alpha DIBSections meets both of these requirements and is used for this sample. To see how a typical operation is implemented, consider the src_atop Porter-Duff operation. In this operation, pixels inside the destination are composited onto the destination. (The concept of "inside" here is based on what happens on the screen. Pixels which are transparent are regarded as "outside" whilst those that are opaque or translucent are "inside"). The equation for this operation is as follows:
Dc' = Sc.Da + Dc(1 - Sa)
Da' = Sa.Da + Da(1 - Sa)
= Da
So to implement we need two DIBSections: a source, and a destination. Then each pixel is considered in the source and destination and the calculation performed. If the two DIBSections are not identically sized, then only the area that is overlapped between the two can be considered. As noted in the True Colour DIBSection article, COM provides a technique whereby any buffer of memory can be made to look like a Visual Basic array. This allows the pixel values to be read very quickly at the expense of some slightly more complex code to create the array:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Type SAFEARRAYBOUND
cElements As Long
lLbound As Long
End Type
Private Type SAFEARRAY2D
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
Bounds(0 To 1) As SAFEARRAYBOUND
End Type
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" _
(Ptr() As Any) As Long
...
Dim bDib() as Byte
Dim tSA As SAFEARRAY2D
With tSA
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = Height
.Bounds(1).lLbound = 0
.Bounds(1).cElements = BytesPerScanLine
.pvData = Ptr ' Pointer to DIB section memory
End With
CopyMemory ByVal VarPtrArray(bDib()), VarPtr(tSA), 4
Casting a buffer of memory to a 2D array The code below shows how the calculation is performed on the individual bytes. Note that whenever two values are multiplied together, it is necessary to divide by 255 to ensure the result is still in range, and the use of long values to prevent overflows during the intermediate calculations.
' Loop through each value in x, 4 bytes at a time.
' 4 bytes = B,G,R,A
For x = srcX To xEnd Step 4
' Loop through each value in y. Note that a DIB
' is usually upside down, so y = 0 is the last row
' and y = height - 1 is the first.
For y = srcY To yEnd
' Dc' = Sc.Da + Dc(1 - Sa)
' Calculate the new red value:
lR = (bDib(x + 2, y) * 1& * bDibDst(x + 3, y)) / 255& + _
bDibDst(x + 2, y) * (255& - bDib(x + 3, y)) / 255&
' Set the new red value:
bDibDst(x + 2, y) = lR
' Calculate the new green value:
lG = (bDib(x + 1, y) * 1& * bDibDst(x + 3, y)) / 255& + _
bDibDst(x + 1, y) * (255& - bDib(x + 3, y)) / 255&
bDibDst(x + 1, y) = lG
' Calculate the new blue value:
lB = (bDib(x, y) * 1& * bDibDst(x + 3, y)) / 255& + _
bDibDst(x, y) * (255& - bDib(x + 3, y)) / 255&
bDibDst(x, y) = lB
' Da ' = Sa.Da + Da(1 - Sa)
' = Da
' no change in alpha
Next y
Next x
The cCompositing ClassThe cCompositing class provided with the download provides implementations for all of the compositing operations described above and a simple interface to access them. To use the class, create an instance of it, and then perform these steps:
The demonstration application provided with the download provides a simple UI which demonstrates each of the compositing operations. All of these operations can be further enhanced by providing a parameterised alpha adjustment to the operation that's being performed. To do this, you just need to adjust all alpha values in the source and/or destination by a constant percentage. This technique is used (for example) in Paint Shop Pro to allow different layers in an Image to be combined in different creative ways. ConclusionThis article has described a rich set of compositing techniques and demonstrates how to perform each of them with reusable VB code.
|
|
|
|
||