May 14, 2024, 09:42:51 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


How to rotate a bitmap (or jpg) in a static control

Started by RitchieF, September 01, 2008, 12:52:58 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

RitchieF

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

joeb

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

LarryMc

create a 2nd bitmap rotated the amount you want and then swap the 2 out based upon lbuttondown/up.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

RitchieF

@ 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

sapero

Here is a simple example, I've created a class with Rotate method.

RitchieF

Sapero,
thanks for your help but I don't have the 'ocidl.inc'

Richard

sapero

Ok, here is a project with precompilled class (CRotateBitmap.o), you don't need the ocidl now.

RitchieF


sapero

September 03, 2008, 04:16:56 PM #8 Last Edit: September 03, 2008, 04:32:09 PM by sapero
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.

RitchieF

Hi Sapero,

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

Thank You,

Richard