From: Guy on
I have a PictureBox control which contains a JPG. I want the user to be
able to rotate the JPG either left or right 90 degrees, nothing else. I
found a pretty cool piece of code which uses PlgBlt. You put the source in
Picture1 and it draws the rotated result in Picture2, based of the value of
a scroll bar. The code appears to work for me but I had to comment out this
line of code to make it work not only with BMPs but also with my JPGs.
Actually, it appears to work with GIFs and JPGs with that line commeted out.

'If (inPicture.Type <> vbPicTypeBitmap) Then Exit Function

Does anyone know why that line is there? Is PlgBlt only expected to work
with BMPs?
Guy

PS. Here's the code, I just added scroll bar values

'http://groups.google.co.uk/group/microsoft.public.vb.winapi/msg/1ed1fe9ecd60e4fa
'---------------------------------------------------------------------------------------------------------------------------
'Here's a quick example of how to use PlgBlt() to draw a rotated Bitmap
whilst retaining it's ratio,
'Drop 2 picture boxes and a horizontal scrollbar onto the form and put an
image in Picture1 then drop in this code and run:
'
'Hope this helps,
' Mike
' - Microsoft Visual Basic MVP -
' E-Mail: ED...(a)mvps.org
' WWW: Http://www.mvps.org/EDais/




'***
Private Declare Function PlgBlt Lib "GDI32.dll" (ByVal hDCDest As Long,
ByRef lpPoint As PointAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal
nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As
Long, ByVal xMask As Long, ByVal yMask As Long) As Long
Private Declare Function CreateCompatibleDC Lib "GDI32.dll" (ByVal hDC As
Long) As Long
Private Declare Function SelectObject Lib "GDI32.dll" (ByVal hDC As Long,
ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "GDI32.dll" (ByVal hDC As Long) As
Long

Private Type PointAPI
X As Long
Y As Long
End Type




Private Sub Form_Load()
HScroll1.Min = 0
HScroll1.Max = 360
HScroll1.SmallChange = 10
HScroll1.LargeChange = 90
HScroll1.Value = 0
End Sub

Private Sub HScroll1_Change()
Call ReDraw
End Sub


Private Sub HScroll1_Scroll()
Call ReDraw
End Sub


Private Sub ReDraw()
Picture2.AutoRedraw = True
Call Picture2.Cls
Call DrawStdPictureRot(Picture2.hDC, 0, 0, HScroll1.Value,
Picture1.Picture)
Call Picture2.Refresh
End Sub







Private Function DrawStdPictureRot(ByVal inDC As Long, ByVal inX As Long,
ByVal inY As Long, ByVal inAngle As Single, ByRef inPicture As StdPicture)
As Long
Dim hDC As Long
Dim hOldBMP As Long
Dim PlgPts(0 To 4) As PointAPI
Dim PicWidth As Long, PicHeight As Long
Dim HalfWidth As Single, HalfHeight As Single
Dim AngleRad As Single


Const Pi As Single = 3.14159
Const HalfPi As Single = Pi * 0.5


' Validate input picture
If (inPicture Is Nothing) Then Exit Function
'If (inPicture.Type <> vbPicTypeBitmap) Then Exit Function


' Get picture size
PicWidth = ScaleX(inPicture.Width, vbHimetric, vbPixels)
PicHeight = ScaleY(inPicture.Height, vbHimetric, vbPixels)


' Get half picture size and angle in radians
HalfWidth = PicWidth / 2
HalfHeight = PicHeight / 2
AngleRad = (inAngle / 180) * Pi


' Create temporary DC and select input picture into it
hDC = CreateCompatibleDC(0&)
hOldBMP = SelectObject(hDC, inPicture.Handle)


If (hOldBMP) Then ' Get angle vectors for width and height
PlgPts(0).X = Cos(AngleRad) * HalfWidth
PlgPts(0).Y = Sin(AngleRad) * HalfWidth
PlgPts(1).X = Cos(AngleRad + HalfPi) * HalfHeight
PlgPts(1).Y = Sin(AngleRad + HalfPi) * HalfHeight


' Project parallelogram points for rotated area
PlgPts(2).X = HalfWidth + inX - PlgPts(0).X - PlgPts(1).X
PlgPts(2).Y = HalfHeight + inY - PlgPts(0).Y - PlgPts(1).Y
PlgPts(3).X = HalfWidth + inX - PlgPts(1).X + PlgPts(0).X
PlgPts(3).Y = HalfHeight + inY - PlgPts(1).Y + PlgPts(0).Y
PlgPts(4).X = HalfWidth + inX - PlgPts(0).X + PlgPts(1).X
PlgPts(4).Y = HalfHeight + inY - PlgPts(0).Y + PlgPts(1).Y


' Draw rotated image

DrawStdPictureRot = PlgBlt(inDC, PlgPts(2), hDC, 0, 0, PicWidth,
PicHeight, 0&, 0, 0)


' De-select Bitmap from DC
Call SelectObject(hDC, hOldBMP)
End If


' Destroy temporary DC
Call DeleteDC(hDC)
End Function



From: Mike Williams on
On 26 Jan, 00:27, "Guy" <some...(a)somewhere.nb.ca> wrote:

> I have a PictureBox control which contains
> a JPG. I want the user to be able to rotate
> the JPG either left or right 90 degrees.
> I found a pretty cool piece of code which
> uses PlgBlt . . . but I had to comment out
> this line of code to make it work not only
> with BMPs but also with my JPGs.
> ' If (inPicture.Type <> vbPicTypeBitmap)
> ' Then Exit Function
> Is PlgBlt only expected to work with BMPs?

Yes. PlgBlt only works with bitmaps. If you want to use PlgBlt to
rotate any other type of image you need to first convert that image
into a bmp and rotate it using PlgBlt and then convert the result back
into the original image type. The initial stage (converting it to a
bmp) is done automatically for you when you load a jpg into a
StdPicture object or into the Picture property of a Control, which is
why it appears to work with a jpg, even though it is actually working
with the bmp. To save the resultant rotated bmp out as a jpeg you need
a conversion utility. Writing onme yourself is virtually out of the
question, because it is a very complex task, but fortunately other
people have already written and distributed libraries that will do it
for you. You'll find lots of them dotted about the net. One very old
one (which still works fine) is the Intel IJL11.DLL library. You can
download some example VB code and the Intel library itself from (watch
for possible word wrap on this link):

http://www.vbaccelerator.com/home/VB/Code/vbMedia/Saving_Pictures_to_JPG/Using_Intel_JPG_Library/article.asp

By the way, even after you have got this all sorted out you still need
to make sure that your system is running at full colour depth to make
the best of it. Any system running at 16 bit colour depth will degrade
the image slightly because the original full colour image you load
into the StdPicture object will effectively be degraded to 16 bit
quality on such systems. There are ways of ovecoming this problem and
of loading jpegs at their full colour depth even machines running 16
bit displays but that it another question in itself and I expect that
you will be happy to either run at full colour depth or to accept the
slight loss of colour detail on systems that do not. Post again though
if you need help with the "load jpeg at full colour depth" stuff.

Mike

From: Mike Williams on
On 26 Jan, 00:27, "Guy" <some...(a)somewhere.nb.ca> wrote:

> I have a PictureBox control which contains
> a JPG.  I want the user to be able to rotate
> the JPG either left or right 90 degrees

. . . by the way, further to me previous response I think there is a
utility out there somewhere that can rotate a jpg image itself by 90
degrees and it works with the jpeg file data itself and does not
therefore require to mess about with temporary bitmaps or PlgBlt or
anything else. I can't find it at the moment, and it might not
actually exist, but something in the back of my head is telling me
that it does exist somewhere ;-)

Mike