Page 1 of 1

[Solved] Old School AlphaBlend

Posted: Fri Mar 31, 2017 11:47 am
by ramme
I have used the win32 Alphablend API since I was a young whipper snapper (Now I am an old whipper snapper)
I found a Purebasic example in the CodeArchiv_v4-Beta Archives called, you guessed it, alphablend.pb.

Here it is.

Code: Select all

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=3268&start=10
; Author: Mischa (updated for PB 4.00 by Flype)
; Date: 30. December 2003
; OS: Windows
; Demo: No


Import "Msimg32.lib" 
  AlphaBlend(dc1, x1, y1, w1, h1, dc2, x2, y2, w2, h2, blend) 
EndImport 

Procedure.l DrawAlphaImage2(hdc, image, x, y, Alpha) 
  Protected tdc.l, object.l, w.l, h.l, blend.l, *blend.BLENDFUNCTION = @blend 
  tdc = CreateCompatibleDC_(hdc) 
  If tdc 
    object = SelectObject_(tdc, ImageID(image)) 
    If object 
      w = ImageWidth(image) 
      h = ImageHeight(image) 
      *blend\SourceConstantAlpha = Alpha 
      AlphaBlend(hdc, x, y, w, h, tdc, 0, 0, w, h, blend) 
      DeleteObject_(object) 
    EndIf 
    DeleteDC_(tdc) 
  EndIf 
EndProcedure 

For i = 1 To 10 
  If CreateImage(i, Random(50)+50, Random(50)+50) 
    If StartDrawing(ImageOutput(i)) 
      Box(0, 0, ImageWidth(i), ImageHeight(i), RGB(Random(255), Random(255), Random(255))) 
      StopDrawing() 
    EndIf 
  EndIf 
Next i 

If OpenWindow(0, 0, 0, 400, 300, "AlphaBlend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  
  hdc = StartDrawing(WindowOutput(0)) 
  
  If hdc 
    For i = 1 To 100 
      For j = 1 To 10 
        DrawAlphaImage2(hdc, j, Random(375), Random(275), i) 
      Next j 
      WindowEvent() 
      Delay(20) 
    Next i 
  EndIf 
  
  StopDrawing() 

  Repeat 
  Until WaitWindowEvent()=#PB_Event_CloseWindow 

EndIf 
It doesn't work, anymore. I wonder if Mischa knows why?
Is there a way to duplicate this API in Purebasic?
It does a great job of blending(morphing) pictures especially fractals.

Re: Old School AlphaBlend

Posted: Fri Mar 31, 2017 12:26 pm
by RASHAD
Hi

Code: Select all

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=3268&start=10
; Author: Mischa (updated for PB 4.00 by Flype)
; Date: 30. December 2003
; OS: Windows
; Demo: No


OpenLibrary(0, "Msimg32.dll")

Procedure.l DrawAlphaImage2(hdc, image, x, y, Alpha)
  Protected tdc.l, object.l, w.l, h.l, blend.l, *blend.BLENDFUNCTION = @blend
  tdc = CreateCompatibleDC_(hdc)
  If tdc
    object = SelectObject_(tdc, ImageID(image))
    If object
      w = ImageWidth(image)
      h = ImageHeight(image)
      *blend\SourceConstantAlpha = Alpha
      CallFunction(0,"AlphaBlend",hdc, x, y, w, h, tdc, 0, 0, w, h, blend)
      DeleteObject_(object)
    EndIf
    DeleteDC_(tdc)
  EndIf
EndProcedure

For i = 1 To 10
  If CreateImage(i, Random(50)+50, Random(50)+50)
    If StartDrawing(ImageOutput(i))
      Box(0, 0, ImageWidth(i), ImageHeight(i), RGB(Random(255), Random(255), Random(255)))
      StopDrawing()
    EndIf
  EndIf
Next i

If OpenWindow(0, 0, 0, 400, 300, "AlphaBlend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 
  hdc = StartDrawing(WindowOutput(0))
 
  If hdc
    For i = 1 To 100
      For j = 1 To 10
        DrawAlphaImage2(hdc, j, Random(375), Random(275), i)
      Next j
      WindowEvent()
      Delay(20)
    Next i
  EndIf
 
  StopDrawing()

  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
CloseLibrary(0)
EndIf 

Re: Old School AlphaBlend

Posted: Fri Mar 31, 2017 12:40 pm
by ramme
Thanks RASHAD,

Your version works great.
I am really impressed.

Re: Old School AlphaBlend

Posted: Fri Mar 31, 2017 7:32 pm
by infratec
Isn't this the same?

Code: Select all

For i = 1 To 10
  If CreateImage(i, Random(50)+50, Random(50)+50)
    If StartDrawing(ImageOutput(i))
      Box(0, 0, ImageWidth(i), ImageHeight(i), RGB(Random(255), Random(255), Random(255)))
      StopDrawing()
    EndIf
  EndIf
Next i

If OpenWindow(0, 0, 0, 400, 300, "AlphaBlend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  If StartDrawing(WindowOutput(0))
    For i = 1 To 100
      For j = 1 To 10
        DrawAlphaImage(ImageID(j), Random(375), Random(275), i)
      Next j
      WaitWindowEvent(20)
    Next i
    StopDrawing()
  EndIf
  
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  
EndIf 
Bernd

Re: Old School AlphaBlend

Posted: Fri Mar 31, 2017 7:55 pm
by firace
And to make sure the entire area is covered:

Code: Select all

For i = 1 To 10
  If CreateImage(i, Random(50)+50, Random(50)+50)
    If StartDrawing(ImageOutput(i))
      Box(0, 0, ImageWidth(i), ImageHeight(i), RGB(Random(255), Random(255), Random(255)))
      StopDrawing()
    EndIf
  EndIf
Next i

If OpenWindow(0, 0, 0, 400, 300, "AlphaBlend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  If StartDrawing(WindowOutput(0))
    For i = 1 To 100
      For j = 1 To 10
         DrawAlphaImage(ImageID(j), Random(575)-100, Random(475)-100, i)
      Next j
      WaitWindowEvent(20)
    Next i
    StopDrawing()
  EndIf
  
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  
EndIf

Re: Old School AlphaBlend

Posted: Sat Apr 01, 2017 12:13 am
by netmaestro
It doesn't work, anymore. I wonder if Mischa knows why?
I don't know if Mischa knows why but I can say why it no longer works. The MsImg32.lib which ships with PureBasic doesn't contain the AlphaBlend function. Probably because PureBasic doesn't use it for any of its native commands. If you use the MsImg32.lib from the platform sdk the function is present but the code still won't run as written because PureBasic already has a native command called AlphaBlend. You can still use it but you have to identify it in the library using its decorated name and give your function a name other than AlphaBlend(). Here I've chosen AlphaBlend_():

Code: Select all

Import "<your platform sdk path to the filel>\Msimg32.lib" 
  AlphaBlend_(dc1, x1, y1, w1, h1, dc2, x2, y2, w2, h2, blend) As "_AlphaBlend@44"
EndImport 
With the code thus modified the original posting works flawlessly here.

Re: Old School AlphaBlend

Posted: Sat Apr 01, 2017 12:53 am
by chi
My two cents...

Code: Select all

Import "gdi32.lib"
  GdiAlphaBlend(hdcDest, xoriginDest, yoriginDest, wDest, hDest, hdcSrc, xoriginSrc, yoriginSrc, wSrc, hSrc, ftn)  
EndImport
Edit: Also not available with vanilla PB!

Re: Old School AlphaBlend

Posted: Sat Apr 01, 2017 3:23 am
by ramme
Thank you for your kind suggestions.
I tried them all and they worked much better than my attempts had.
I am having difficulty with one concept in Purebasic, though.
I had just about figured out how flipbuffers() work and yet
the alphablend examples had no flipping buffers.
How are the boxes visible? What am I missing?

Re: Old School AlphaBlend

Posted: Sat Apr 01, 2017 3:30 am
by netmaestro
FlipBuffers() is only for the Sprite library. Sprites and 2D drawing are rendered to memory first and FlipBuffers() then blits the memory to the visible screen. With regular 2D or Vector drawing (which includes image display) there is no intermediate step, drawing is done straight to the visible screen.

Re: Old School AlphaBlend

Posted: Sat Apr 01, 2017 4:45 am
by ramme
Thank you netmaestro.

That is good to know. Your explanation absolutely cleared
things up for me.
I think that I can figure out how to replace the boxes
with images now.

Re: Old School AlphaBlend

Posted: Sun Apr 02, 2017 5:18 am
by ramme
These are my final results:

(1)Window Alphablend

Code: Select all

UseJPEGImageDecoder()

If OpenWindow(0, 0, 0, 1024, 768, "AlphaBlend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If LoadImage(0, "Video/Pictures/Fractal/500.jpg")
    StartDrawing(WindowOutput(0))
      DrawImage(ImageID(0), 0, 0 , 1024, 768) 
    StopDrawing()
  EndIf

  LoadImage(1, "Video/Pictures/Fractal/501.jpg")
  If StartDrawing(WindowOutput(0)) 
    For i=0 To 255
      DrawAlphaImage(ImageID(1), 0, 0, i)  
      If i<50 :Delay(100):EndIf
    Next i
    StopDrawing()
  EndIf
  
  Repeat
    Delay(100)
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  
EndIf
(2)Screen AlphaBlend

Code: Select all

UseJPEGImageDecoder()

If InitSprite() And InitKeyboard() And OpenScreen(1024, 768,32, "AlphaBlend")
  If LoadSprite(0, "Video/Pictures/Fractal/500.jpg",#PB_Sprite_AlphaBlending ) And LoadSprite(1,"Video/Pictures/Fractal/501.jpg",#PB_Sprite_AlphaBlending )
    For i=0 To 255
      ClearScreen(RGB(0,0,0)) 
      DisplayTransparentSprite(0,0,0,255-i)
      DisplayTransparentSprite(1,0,0,i)  
      FlipBuffers()
      If i=0 
        Delay(2000)
      Else
        Delay(20)
      EndIf
    Next i
  EndIf
  
; wait For a keypress
  Repeat
    ExamineKeyboard()
    Delay(10)
  Until KeyboardReleased(#PB_Key_All)
EndIf
The strange delays in the code are my crude attempts to deal with the non-linear visual aspect.
I am not sure how to include attachments in this forum, but 1024X768 or greater jpgs should do.
Thanks to you all ,again, for your help. It was greatly appreciated.