AHK实现D2D图片渲染动效

 

打包下载地址:

 

相关阅读:

显示 DWM 缩略图的未记录api

代码片段:

/*	DirectComposition
  Sample 		: how to create and initialize the minimum set of Microsoft DirectComposition objects needed to create a simple composition.
  OS Version	: Win8
  Library		: base.ahk dcomp.ahk
  Website		: 
*/
; https://www.autohotkey.com/boards/viewtopic.php?p=422221#p422221
#SingleInstance,force
#Include <base>
#Include <dcomp>
SetWorkingDir %A_ScriptDir%

Gui,main: new,hwndhgui
Gui,main: add,button, x500 y30 w100 h30 vbtn_Rotate3D gbtn_event,旋转3D效果
Gui,main: add,button, x500 y90 w100 h30 vbtn_Scale3D gbtn_event,缩放3D效果
Gui,main: add,button, x500 y150 w100 h30 vbtn_Translate3D gbtn_event,平移3D效果
Gui,main: add,button, x500 y210 w100 h30 vbtn_Opacity gbtn_event, 逐渐透明
Gui,main: show, w640 h480, DirectComposition Sample

; Step 1: Create the Direct3D device object
; Step 2: Retrieve a pointer to the DXGI object
; Step 3: Create the DirectComposition device object
DCompDevice:=new IDCompositionDevice

; Step 4: Create the composition target object
DCompTarget:=DCompDevice.CreateTargetForHwnd(hgui)

if FileExist("user.bmp")
    Compose3D(DCompDevice,DCompTarget)
 else
    MsgBox 0x10, , 请在目录下存在 “user.bmp”,做演示之用。
return

btn_event:
  if (A_GuiControl="btn_Rotate3D")
    Compose3D(DCompDevice,DCompTarget,"Rotate3D")
  else if (A_GuiControl="btn_Scale3D")
    Compose3D(DCompDevice,DCompTarget,"Scale3D")
  else if (A_GuiControl="btn_Translate3D")
    Compose3D(DCompDevice,DCompTarget,"Translate3D")
  else if (A_GuiControl="btn_Opacity")
    Compose3D(DCompDevice,DCompTarget,"Opacity")
return

LoadResourceGDIBitmap(){
  return DllCall("LoadImage","ptr",0,"str","user.bmp","uint",0,"int",0,"int",0,"uint",0x10)
}

Compose3D(DCompDevice,DCompTarget,action=""){
  static init:=1,hBitmap,bitmapWidth,bitmapHeight,Surface
  if init{
    init:=0
  ; Step 6: Create a composition surface and render a bitmap to the surface
  hBitmap:=LoadResourceGDIBitmap()
  Surface:=CreateGDIRenderedDCompSurface(DCompDevice,hBitmap,bitmapWidth,bitmapHeight)
  }	
  
  ; Step 5: Create a visual object
  Visual:=DCompDevice.CreateVisual()
  
  ; Step 7: Bind surface to visual and set the properties of the visual object
  Visual.SetContent(Surface)

  if (action="Rotate3D"){
    Rotate3D:=DCompDevice.CreateRotateTransform3D()
    EffectGroup:=DCompDevice.CreateEffectGroup()
    
    Animation:=DCompDevice.CreateAnimation()
    Animation.AddCubic(0,0,360,0,0)
    Animation.End(1,360)
    
    Rotate3D.SetAngle(Animation)
    Rotate3D.SetAxisX(1)
    Rotate3D.SetAxisY(1)
    Rotate3D.SetAxisZ(1)
    
    Rotate3D.SetCenterX(bitmapWidth/2)
    Rotate3D.SetCenterY(bitmapHeight/2)
    
    EffectGroup.SetTransform3D(Rotate3D)
    Visual.SetEffect(EffectGroup)
    
  }else if (action="Scale3D"){
    Scale3D:=DCompDevice.CreateScaleTransform3D()
    EffectGroup:=DCompDevice.CreateEffectGroup()
    
    Animation:=DCompDevice.CreateAnimation()
    Animation.AddCubic(0,1,-1,0,0)
    Animation.AddCubic(0.5,0.5,1,0,0)
    Animation.End(1,1)
    
    Scale3D.SetScaleX(Animation)
    Scale3D.SetScaleY(Animation)
    Scale3D.SetScaleZ(Animation)
    Scale3D.SetCenterX(bitmapWidth/2)
    Scale3D.SetCenterY(bitmapHeight/2)
    
    EffectGroup.SetTransform3D(Scale3D)
    Visual.SetEffect(EffectGroup)
    
  }else if (action="Translate3D"){
    Translate3D:=DCompDevice.CreateTranslateTransform3D()
    EffectGroup:=DCompDevice.CreateEffectGroup()
    
    AnimationX:=DCompDevice.CreateAnimation()
    AnimationX.AddCubic(0,0,80,0,0)
    AnimationX.AddCubic(0.5,40,0,0,0)
    AnimationX.AddCubic(1,40,-80,0,0)
    AnimationX.AddCubic(1.5,0,0,0,0)
    AnimationX.End(2,0)
    AnimationY:=DCompDevice.CreateAnimation()
    AnimationY.AddCubic(0,0,0,0,0)
    AnimationY.AddCubic(0.5,0,80,0,0)
    AnimationY.AddCubic(1,40,0,0,0)
    AnimationY.AddCubic(1.5,40,-80,0,0)
    AnimationY.End(2,0)
    
    Translate3D.SetOffsetX(AnimationX)
    Translate3D.SetOffsetY(AnimationY)
    
    EffectGroup.SetTransform3D(Translate3D)
    Visual.SetEffect(EffectGroup)
    
  }else if (action="Opacity"){
    EffectGroup:=DCompDevice.CreateEffectGroup()
    
    Animation:=DCompDevice.CreateAnimation()
    Animation.AddCubic(0,1,-1,0,0)
    Animation.AddCubic(1,0,1,0,0)
    Animation.End(2,1)

    EffectGroup.SetOpacity(Animation)
    Visual.SetEffect(EffectGroup)
  }
  
  ; Step 8: Set the root visual of the visual tree
  DCompTarget.SetRoot(Visual)
  
  ; Step 9: Commit the composition
  DCompDevice.Commit() 
  
  ; Step 10: Free the DirectComposition objects
  ; Visual=
}

CreateGDIRenderedDCompSurface(DCompDevice,Bitmap,ByRef bitmapWidth,ByRef bitmapHeight){
  ; Get information about the bitmap.
  ; bmp:=struct("LONG bmType;LONG bmWidth;LONG bmHeight;LONG bmWidthBytes;WORD bmPlanes;WORD bmBitsPixel;LPVOID bmBits;")
        VarSetCapacity(bmp, A_PtrSize*2+16, 0)
  DllCall("GetObject","ptr",Bitmap,"int", A_PtrSize*2+16,"ptr", &bmp)
  
  ; Save the bitmap dimensions.
  bitmapWidth := NumGet(bmp, 4, "uint")
  bitmapHeight := NumGet(bmp, 8, "uint")
  
  ; Create a DirectComposition-compatible surface that is the same size as the bitmap. 
  ; The DXGI_FORMAT_B8G8R8A8_UNORM flag is required for rendering on the surface using GDI via GetDC.
  ; DXGI_FORMAT_B8G8R8A8_UNORM:=87 , DXGI_ALPHA_MODE_IGNORE:=3
  DCSurface:=DCompDevice.CreateSurface(bitmapWidth, bitmapHeight, 87, 3)
  
  ; Begin rendering to the surface.
  output:=DCSurface.BeginDraw(0,guid(IID_DXGISurface1,"{4AE63092-6327-4c1b-80AE-BFE12EA32B86}"))
  DXGISurface:=output.1
  pointOffset_x:=output.2
        pointOffset_y:=output.3
  
  ; Get the device context (DC) for the surface.
  DllCall(vt(DXGISurface,11),"ptr",DXGISurface,"int",0,"ptr*",SurfaceDC,"uint") ; GetDC
  
  ; Create a compatible DC and select the surface into the DC.
  BitmapDC:=DllCall("CreateCompatibleDC","ptr",SurfaceDC)
  BitmapOld:=DllCall("SelectObject","ptr",BitmapDC,"ptr",Bitmap)
  DllCall("BitBlt","ptr",SurfaceDC,"int",pointOffset_x,"int",pointOffset_y,"int",bitmapWidth,"int",bitmapHeight,"ptr",BitmapDC,"int",0,"int",0,"int",0xCC0020) ; SRCCOPY:=0xCC0020
  DllCall("SelectObject","ptr",BitmapDC,"ptr",BitmapOld)	

  ; End the rendering.
  DCSurface.EndDraw()
  
  ; Free the surface pointer.
  DXGISurface=
    
  return DCSurface
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。