|
Prev: opening file type problems
Next: MS Access BAT file unzipping and renaming - Directory DOS issue
From: Guy on 25 Jan 2008 19:27 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 26 Jan 2008 05:50 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 26 Jan 2008 05:54 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
|
Pages: 1 Prev: opening file type problems Next: MS Access BAT file unzipping and renaming - Directory DOS issue |