2011-09-01 71 views
0

我正在使用API​​调用来转换Bitmap对象。我有各种物理变换(旋转,翻转,缩放,位移)以及一些颜色调整(反转,亮度和对比度)将旋转和颜色调整应用于GDI DeviceContext会导致颜色重置

一切正常,除了当我使用旋转或剪切变换与颜色调整。在这种情况下,颜色会恢复为原始图像。

关于这个问题有趣的是它似乎依赖于XForm矩阵中的非对角因子(eM12和eM21)。例如,这里是旋转矩阵:

Public Sub RotateClockwise(Radians As Single) 
    With XFormMatrix 
     .eM11 = Cos(Radians) 
     .eM12 = Sin(Radians) 
     .eM21 = -Sin(Radians) 
     .eM22 = Cos(Radians) 
     .eDx = 0 
     .eDy = 0 
    end with 
end sub 

每当EM12或EM21是不为零,那么我的颜色就消失了!同样的问题也发生例如与剪切变换:

Public Sub Shear(ShearFactorX As Single, ShearFactorY As Single) 
    With XFormMatrix 
     .eM11 = 1 
     .eM12 = ShearFactorX 
     .eM21 = ShearFactorY 
     .eM22 = 1 
     .eDx = 0 
     .eDy = 0 
    End With 
End Sub 

这里是子(略),我申请转型并设置颜色调整

Private Declare Function CreateCompatibleDC Lib "GDI32.dll" (ByVal hDC As Long) As Long 
Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hDC As Long, pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long 
Private Declare Function SelectObject Lib "GDI32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long 
Private Declare Function SetWorldTransform Lib "gdi32" (ByVal hDC As Long, ByRef lpXform As xForm) As Long 
Private Declare Function SetColorAdjustment Lib "GDI32.dll" (ByVal hDC As Long, ByRef lpCA As ColorAdjustment) As Long 
Private Declare Function StretchBlt Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long 

Private Sub TransformAndDraw() 
'Initialise objects 
BufferDC = CreateCompatibleDC(0) 
BgBuffer = CreateDIBSection(hDC:=BufferDC, pBitmapInfo:=bmi, un:=DIB_RGB_COLORS, lplpVoid:=0&, handle:=0&, dw:=0&) 
SelectObject BufferDC, BgBuffer 

'Define the transformation matrices 
SetWorldTransform hDC:=BufferDC, lpXform:=XFormMatrix 

' Apply this colour adustment to the Buffer DC 
SetColorAdjustment hDC:=BufferDC, lpCA:=NewAdjust 

'load picSource into the Buffer and apply scaling factor 
    StretchBlt hDC:=BufferDC, _ 
       x:=0, _ 
       y:=0, _ 
       nWidth:=srcBmp.bmWidth * xsize, _ 
       nHeight:=srcBmp.bmHeight * xsize, _ 
       hSrcDC:=srcHDC, _ 
       xSrc:=0, _ 
       ySrc:=0, _ 
       nSrcWidth:=srcBmp.bmWidth, _ 
       nSrcHeight:=srcBmp.bmHeight, _ 
       dwRop:=vbSrcCopy 

'Paint the UserControl surface with the Buffer 

'reset and delete objects 
End Sub 

总结我的问题:有某种方式我可以同时使用SetWorldTransformSetColorAdjustment在我的XForm转换中对非对角线因子使用非零值时?

回答

0

好的,我找到了解决方案。我将物理转换和颜色调整分为两个独立的对StretchBlt的调用。在这之间,我重置Image-Buffer中的Xform矩阵,以便在颜色调整过程中不存在。

在第一次调用中,外部图片源被加载到缓冲区并根据Xform矩阵拉伸。 在第二次调用中,为了应用颜色调整,将缓冲区涂在自身上。

Private Sub TransformAndDraw() 
    'Initialise objects 
    BufferDC = CreateCompatibleDC(0) 
    BgBuffer = CreateDIBSection(hDC:=BufferDC, pBitmapInfo:=bmi, un:=DIB_RGB_COLORS, lplpVoid:=0&, handle:=0&, dw:=0&) 
    SelectObject BufferDC, BgBuffer 

    'extract the original transform-settings 
    OldGraphicsMode = SetGraphicsMode(hDC:=BufferDC, iMode:=GM_ADVANCED) 
    GetWorldTransform hDC:=BufferDC, lpXform:=OldMatrix 
    ' Get the current (default) colour adjustment 
    OldStretchMode = SetStretchBltMode(hDC:=BufferDC, nStretchMode:=HALFTONE) 
    OrigAdjust.caSize = Len(OrigAdjust) 
    GetColorAdjustment hDC:=BufferDC, lpCA:=OrigAdjust 

    'Define the transformation matrices 
    SetWorldTransform hDC:=BufferDC, lpXform:=XFormMatrix 

    'load picSource into the Buffer and apply scaling factor 
    'hSrcDC:=srcHDC 
    StretchBlt hDC:=BufferDC, _ 
       x:=0, _ 
       y:=0, _ 
       nWidth:=srcBmp.bmWidth * xsize, _ 
       nHeight:=srcBmp.bmHeight * xsize, _ 
       hSrcDC:=srcHDC, _ 
       xSrc:=0, _ 
       ySrc:=0, _ 
       nSrcWidth:=srcBmp.bmWidth, _ 
       nSrcHeight:=srcBmp.bmHeight, _ 
       dwRop:=vbSrcCopy 

    'revert the transform settings, these can conflict with the colour adjustment 
    SetWorldTransform hDC:=BufferDC, lpXform:=OldMatrix 
    SetGraphicsMode hDC:=BufferDC, iMode:=OldGraphicsMode 

    ' Apply the colour adustment to the Buffer DC 
    SetColorAdjustment hDC:=BufferDC, lpCA:=NewAdjust 

    'now apply a second call to StretchBlt, this time painting the buffer with itself! 
    'hSrcDC:=BufferDC! 
    StretchBlt hDC:=BufferDC, _ 
       X:=0, _ 
       Y:=0, _ 
       nWidth:=UserControl.ScaleWidth, _ 
       nHeight:=UserControl.ScaleHeight, _ 
       hSrcDC:=BufferDC, _ 
       xSrc:=0, _ 
       ySrc:=0, _ 
       nSrcWidth:=UserControl.ScaleWidth, _ 
       nSrcHeight:=UserControl.ScaleHeight, _ 
       dwRop:=vbSrcCopy 

    'now revert the colour adjustment settings 
    SetStretchBltMode hDC:=BufferDC, nStretchMode:=OldStretchMode 
    SetColorAdjustment hDC:=BufferDC, lpCA:=OrigAdjust 

    'Paint the UserControl surface with the Buffer 
    BitBlt hDestDC:=UserControl.hDC, _ 
      X:=0, _ 
      Y:=0, _ 
      nWidth:=UserControl.ScaleWidth, _ 
      nHeight:=UserControl.ScaleHeight, _ 
      hSrcDC:=BufferDC, _ 
      xSrc:=0, _ 
      ySrc:=0, _ 
      dwRop:=vbSrcCopy 

    'Delete objects! 
    DeleteDC BufferDC 
    DeleteObject BgBuffer 
    UserControl.Refresh 
End Sub