Rotating an image control

dmarco
dmarco used Ask the Experts™
on
Hi friends,

I have a form with an Image control that shows a picture (a jpg file).
Is it possible to rotate (90° clockwise and/or counterclokw.) the picture ? or is it possible to rotate the whole form window?
please, post a code sample ..
thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
There sure is...Here's all you need to know.  If you need help with it, just ask:  Note:  This is for fun purposes only,  The form you turn the image around on will not be usable because the buttons acutally stay where they are, but the picture rotates.  You can also change the hwnd from the Form's hwnd to the picturebox you are using to see it happen correctly on a picturebox:

Here's a fun one:  Turn your form upside down (I know I got the points already), but we can all get a good laugh.  After the form is upside down, the buttons actually click where they used to be, not where they are now).  Of course it's not an easter egg because it's on Command1_click, but combining with rspahitz would turn it into one.

Private Type RECT
       Left As Long
       Top As Long
       Right As Long
       Bottom As Long
End Type
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC 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 dwRop As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) 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 Command1_Click()

Dim R As RECT
Dim screenDc As Long
Dim Bitmap As Long
Dim Tmphdc As Long
Dim Junk As Long
Dim hwnd As Long

'Here's where you would change the code if you wanted to rotate the picturebox
hwnd = Me.hwnd
'would become hwnd = picture1.hwnd
GetWindowRect hwnd, R
screenDc = GetWindowDC(GetDesktopWindow)
Bitmap = CreateCompatibleBitmap(screenDc, R.Right - R.Left, R.Bottom - R.Top)
Tmphdc = CreateCompatibleDC(screenDc)
Junk = SelectObject(Tmphdc, Bitmap)
'There's the rotation magic
BitBlt Tmphdc, 0, 0, R.Right - R.Left, R.Bottom - R.Top, screenDc, R.Left, R.Top, &H330008
StretchBlt screenDc, R.Left, R.Top + (R.Bottom - R.Top), (R.Right - R.Left), (R.Bottom - R.Top) * -1, Tmphdc, 0, 0, (R.Right - R.Left), (R.Bottom - R.Top), &H330008
SelectObject Tmphdc, Junk
DeleteObject Bitmap: DeleteDC Tmphdc
End Sub
Just ask for help with this if it seems difficult to you.
StretcBlt trick doesn't rotate image - it "flip" or "mirror" it. Check out my sample on image processing: http://www.freevbcode.com/ShowCode.Asp?ID=4997
There are rotate staff too.

Regards
Ark
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
To twalgrave,

I have inserted your code into my program without difficulty and it works, but...the picture is flipped upside down and not rotated ( Ark's comment is correct). What I need is simply a photo viewer, where sometimes one needs to rotate a picture 90° on the right/left, because it has been shooted with a rotated camera.

To Ark,

Your program is a very nice tool for manipulating graphic images, but , as stated above, my need is limited to one simple task. I have tested the rotation function in your demo and it works correctly.
Now,.. it is a very hard work for me to extract only the Rotate method from the cImgProcess class,  along with the ProcessImage method from the cPictureEx class and so on.....I wouldn't like to add ALL your program to my one, this seems me unuseful.
Do you have any suggestion about..?

However, thanks to both.
Marco

Author

Commented:
Ok, I did the work.
I have the same problem, I have tried to extract the code from Arks program with some difficulty.

Could you please post the extracted code that you have for rotating an image box with a jpeg in it.

Many thanks,

Nick.

Commented:
Same problem here dude.. Need to rotate 90 degrees.. help me out with the placement of variables.., i cant figure it out...  i got it to zoom in and out.. which works great, but i cant figure out how to rotate the object
Done it now.

Here try this:

put the following code into a module:

'*****************************************************
Option Explicit

Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long

' Rgb Values Information
Private Type RGBTriplet
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type

' More specific Bitmap info.
Private Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type

' Bitmap Information
Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors As RGBTriplet
End Type

Public Function DoRotate(lPicture As Image, pic1 As PictureBox, pic2 As PictureBox) As Integer
    Dim bmi As BITMAPINFO, bits() As RGBTriplet, x As Long, y As Long, aRot() As RGBTriplet, mx As Long, my As Long
    On Error Resume Next
   
    ' Load in RGB Pic, since can't do effects with an Image Control, has to be a PictureBox Control...
    pic1.Picture = lPicture.Picture
    pic1.Refresh
    DoEvents
   
    ' Clear the pics before doing anything
    pic1.Cls
    pic2.Cls

    pic2 = pic1
    pic2.Move 0, 0, pic1.ScaleHeight, pic1.ScaleWidth
   
    mx = pic1.ScaleWidth - 1
    my = pic1.ScaleHeight - 1
    DoEvents
    ReDim bits(mx, my)
    ReDim aRot(my, mx)
   
    With bmi.bmiHeader
        .biSize = 40
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = 0
        .biClrUsed = 0
        .biClrImportant = 0
        .biSizeImage = (mx + 1) * (my + 1)
        .biWidth = mx + 1
        .biHeight = my + 1
    End With
   
    x = GetDIBits(pic1.hdc, pic1.Image.Handle, 0, my + 1, bits(0, 0), bmi, 0)
    For x = 0 To mx
        For y = 0 To my
            aRot(my - y, x) = bits(x, y)
        Next y
    Next x
    With bmi.bmiHeader
        .biSize = 40
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = 0
        .biClrUsed = 0
        .biClrImportant = 0
        .biSizeImage = (mx + 1) * (my + 1)
        .biWidth = my + 1
        .biHeight = mx + 1
    End With
    x = SetDIBits(pic2.hdc, pic2.Image.Handle, 0, bmi.bmiHeader.biHeight, aRot(0, 0), bmi, 0)
   
    pic2.Picture = pic2.Image
    pic2.Refresh
    DoEvents
    pic1.Picture = pic2.Picture
    pic1.Refresh
    DoEvents

    lPicture.Picture = LoadPicture()
    lPicture.Picture = pic1.Picture
    lPicture.Refresh
    DoEvents

End Function



'*****************************************************


Now, on a form, put 3 controls :
   Img (ImageBox)
   OldPic (PictureBox - not visible)
   NewPic (PictureBox - not visible)

Make sure the scalemode is set to pixels on everything.

Then add a button to the form

On click put :
   DoRotate Img, oldPic, newPic

Put an image in the image box and run the program. With each click, the picture in the image box will rotate 90 degrees!!!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial