IonicWind Software

IWBasic => GUI Central => Topic started by: RitchieF on September 01, 2008, 12:52:58 PM

Title: How to rotate a bitmap (or jpg) in a static control
Post by: RitchieF on September 01, 2008, 12:52:58 PM
I want to rotate a bmp in a static control to show the user an optical feedback of his input.
The rotation must be made in any arbitrary angle.
I found some example code for moving the bmp within the control if it is bigger than the control but no hint for rotating in an arbitrary angle.
Is there a way to do this or can the bmp only be rotated in 90 degrees steps ?

Thanks

Richard
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: joeb on September 01, 2008, 01:21:22 PM
Anyone correct me if I'm wrong...

You would have to load the BMP into a sprite use SPRITEANGLE command to rotate it to the angle, your control would be calibrated from 0 to 359(degrees).
Then paste the sprite back to the BMP.

Hope that's what you are trying to achieve.

Joe
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: LarryMc on September 01, 2008, 01:28:23 PM
create a 2nd bitmap rotated the amount you want and then swap the 2 out based upon lbuttondown/up.

Larry
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: RitchieF on September 02, 2008, 12:04:54 PM
@ joe: I don't want to create a DirectX-screen  to work with sprites

@ Larry : Exactly this is what I don't know how to achieve.

Here is some VB-code which does it right (I have a friend who works with VB so I could see the code working) but I have no experience in porting VB-code to EBasic( I found this code at DEVX.com) :
RotateBitmap - Rotate a 256-color bitmap by any angle

Option Explicit

' This structure holds Bitmap information
Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type

' This structure holds SAFEARRAY info
Private Type SafeArray2
    cDims As Integer
    fFeatures As Integer
    cbElements As Long
    cLocks As Long
    pvData As Long
    cElements1 As Long
    lLbound1 As Long
    cElements2 As Long
    lLbound2 As Long
End Type

' API declares
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As _
    Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal _
    hObject As Long, ByVal nCount As Long, lpObject As Any) As Long

' Rotate a 256-color bitmap by any angle:
'   sourcePB is the source PictureBox control (may be hidden)
'   destPB is the destination PictureBox control
'   XC, YC are the coordinates of the rotation center
'   ANGLE is the rotation angle in degrees
'
' IMPORTANT: the source and destination PictureBox control must initially
' contain the *same* bitmap, to ensure that size and color palette
' are correctly initialized.

' Example:
'    'Load the same image in both source (hidden) and destination controls
'    Picture1.Picture = LoadPicture("d:\winnt\gone fishing.bmp")
'    Picture2.Picture = LoadPicture("d:\winnt\gone fishing.bmp")
'    ' Rotate by 360ÃÆ'ââ,¬Å¡Ãƒâ€šÃ,°   
'    Dim a As Single
'    For a = 0 To 360 Step 5
'        RotatePicture Picture1, Picture2, 50, 50, a
'    Next


Sub RotatePicture(sourcePB As PictureBox, destPB As PictureBox, xc As Long, _
    yc As Long, degrees As Single)
    Const PI As Single = 3.141592653
    Dim pict1() As Byte
    Dim pict2() As Byte
    Dim p1 As SafeArray2, p2 As SafeArray2
    Dim bmp1 As BITMAP, bmp2 As BITMAP
   
    Dim radians As Single
    Dim angle As Single, angle0 As Single
    Dim distance As Single
    Dim deltaX As Long, deltaY As Long
    Dim x As Long, y As Long
    Dim x0 As Long, y0 As Long
   
    ' get bitmap info
    GetObjectAPI sourcePB.Picture, Len(bmp1), bmp1
    GetObjectAPI destPB.Picture, Len(bmp2), bmp2

    If bmp1.bmPlanes <> 1 Or bmp1.bmBitsPixel <> 8 Or bmp2.bmPlanes <> 1 Or _
        bmp2.bmBitsPixel <> 8 Then
        MsgBox "This routine supports 256-color bitmaps only", vbCritical
        Exit Sub
    End If
   
    ' have the local matrices point to bitmap pixels
    With p1
        .cbElements = 1
        .cDims = 2
        .lLbound1 = 0
        .cElements1 = bmp1.bmHeight
        .lLbound2 = 0
        .cElements2 = bmp1.bmWidthBytes
        .pvData = bmp1.bmBits
    End With
    CopyMemory ByVal VarPtrArray(pict1), VarPtr(p1), 4
   
    With p2
        .cbElements = 1
        .cDims = 2
        .lLbound1 = 0
        .cElements1 = bmp2.bmHeight
        .lLbound2 = 0
        .cElements2 = bmp2.bmWidthBytes
        .pvData = bmp2.bmBits
    End With
    CopyMemory ByVal VarPtrArray(pict2), VarPtr(p2), 4
   
    ' convert the angle into radians
    radians = degrees / (180 / PI)
   
    ' rotate the picture
       
    For x = 0 To bmp1.bmWidth - 1
        For y = 0 To bmp1.bmHeight - 1
            deltaX = x - xc
            deltaY = y - yc
            If deltaX > 0 Then
                angle = Atn(deltaY / deltaX)
            ElseIf deltaX < 0 Then
                angle = PI + Atn(deltaY / deltaX)
            Else
                If deltaY > 0 Then angle = PI / 2 Else angle = PI * 3 / 2
            End If
            angle0 = angle - radians
            distance = Sqr(deltaX * deltaX + deltaY * deltaY)
           
            x0 = xc + distance * Cos(angle0)
            y0 = yc + distance * Sin(angle0)
           
            If x0 >= 0 And x0 <= UBound(pict1, 1) And y0 >= 0 And y0 <= UBound _
                (pict1, 2) Then
                pict2(x, y) = pict1(x0, y0)
            Else
                pict2(x, y) = 0
            End If
           
        Next
    Next
   
    ' release arrays
    CopyMemory ByVal VarPtrArray(pict1), 0&, 4
    CopyMemory ByVal VarPtrArray(pict2), 0&, 4
   
    ' show the rotated bitmap
    destPB.Refresh
End Sub

' Support routine

Private Function VarPtrArray(arr As Variant) As Long
    CopyMemory VarPtrArray, ByVal VarPtr(arr) + 8, 4
End Function

Francesco Balena


Richard
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: sapero on September 02, 2008, 03:42:34 PM
Here is a simple example, I've created a class with Rotate method.
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: RitchieF on September 02, 2008, 11:19:08 PM
Sapero,
thanks for your help but I don't have the 'ocidl.inc'

Richard
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: sapero on September 03, 2008, 03:50:13 AM
Ok, here is a project with precompilled class (CRotateBitmap.o), you don't need the ocidl now.
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: RitchieF on September 03, 2008, 07:35:22 AM
That's it !! ;D

It works .

Thank you, Sapero

Richard
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: sapero on September 03, 2008, 04:16:56 PM
Here is the second method: Computing the source point for each destination point. Result is much better than in previous example.
Added a virtual method that you can use to code your own rotation.
Title: Re: How to rotate a bitmap (or jpg) in a static control
Post by: RitchieF on September 06, 2008, 10:41:33 AM
Hi Sapero,

this is a great help for me. Runs perfect here.

Thank You,

Richard