This exercise has forced me to learn a lot about the graphics object and graphics transformations.
The way I handle this problem is to create a module-level graphics object which will handle all of our drawing. We can at any time access the contents of the grapics object through it's associated bitmap. We need two module-level bitmaps: one to hold the original picture which we will continually redraw to the graphics object; and the other to store the pixel data of the graphics object.
At the Module levelIn the formVB Code:
[FONT=Courier New] [COLOR=#0000FF]Private[/COLOR] OrigBitMap [COLOR=#0000FF]As[/COLOR] Bitmap [COLOR=#0000FF]Private[/COLOR] bm [COLOR=#0000FF]As[/COLOR] Bitmap [COLOR=#0000FF]Private[/COLOR] g [COLOR=#0000FF]As[/COLOR] Graphics[/FONT]Note that all the transformations are cumulative. This means that if we want to rotate by a certain amount, we have to know how much we've rotated already. Same goes for scaling. Here are the new functions for rotation and scaling.VB Code:
[FONT=Courier New] [COLOR=#007A00]'OrigBitMap will hold our original picture [/COLOR] OrigBitMap = [COLOR=#0000FF]New[/COLOR] Bitmap(lAppPath & "[COLOR=#7A0000]\Tiger.bmp[/COLOR]") PictureBox1.Width = CInt(OrigBitMap.Width * 2) PictureBox1.Height = CInt(OrigBitMap.Height * 2) PosX = CType((PictureBox1.ClientSize.Width - OrigBitMap.Width) / 2, [COLOR=#0000FF]Single[/COLOR]) PosY = CType((PictureBox1.ClientSize.Height - OrigBitMap.Height) / 2, [COLOR=#0000FF]Single[/COLOR]) [COLOR=#007A00]'associate a bitmap (bm) with the drawing surface (g) [/COLOR] [COLOR=#007A00]'make it the same size as our picturebox [/COLOR] bm = [COLOR=#0000FF]New[/COLOR] Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height) g = Graphics.FromImage(bm) [COLOR=#007A00]'our 1st transformation puts the image in the middle [/COLOR] g.TranslateTransform(PosX, PosY, MatrixOrder.Append) g.DrawImage(OrigBitMap, 0, 0) [COLOR=#007A00]'show the image in the picturebox [/COLOR] PictureBox1.Image = bm[/FONT]And these are called from the trackbars like soVB Code:
[FONT=Courier New] [COLOR=#0000FF]Public[/COLOR] [COLOR=#0000FF]Sub[/COLOR] RotateImage([COLOR=#0000FF]ByVal[/COLOR] Gr [COLOR=#0000FF]As[/COLOR] Graphics, [COLOR=#0000FF]ByVal[/COLOR] mRotAngle [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR]) [COLOR=#0000FF]Static[/COLOR] OldAngle [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 0 [COLOR=#007A00]'move center of image to origin before rotating [/COLOR] Gr.TranslateTransform(-CSng(PictureBox1.ClientSize.Width / 2), _ -CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append) [COLOR=#007A00]'rotate image by the additional amount [/COLOR] Gr.RotateTransform(mRotAngle - OldAngle, MatrixOrder.Append) [COLOR=#007A00]'move image center back to picbox center [/COLOR] Gr.TranslateTransform(CSng(PictureBox1.ClientSize.Width / 2), _ CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append) [COLOR=#007A00]'clear old drawing [/COLOR] Gr.Clear(PictureBox1.BackColor) [COLOR=#007A00]'draw new image [/COLOR] Gr.DrawImage(OrigBitMap, 0, 0) [COLOR=#007A00]'save current rotation angle [/COLOR] OldAngle = mRotAngle [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub [/COLOR] [COLOR=#0000FF]Public[/COLOR] [COLOR=#0000FF]Sub[/COLOR] ZoomImage([COLOR=#0000FF]ByVal[/COLOR] Gr [COLOR=#0000FF]As[/COLOR] Graphics, [COLOR=#0000FF]ByVal[/COLOR] scalex [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1, [COLOR=#0000FF]ByVal[/COLOR] scaley [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1) [COLOR=#007A00]'move center of image to origin before scaling [/COLOR] Gr.TranslateTransform(-CSng(PictureBox1.ClientSize.Width / 2), _ -CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append) [COLOR=#007A00]'scale image by new factor [/COLOR] Gr.ScaleTransform(scalex, scaley, MatrixOrder.Append) [COLOR=#007A00]'move image center back to picbox center [/COLOR] Gr.TranslateTransform(CSng(PictureBox1.ClientSize.Width / 2), _ CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append) [COLOR=#007A00]'clear old drawing [/COLOR] Gr.Clear(PictureBox1.BackColor) [COLOR=#007A00]'draw new image [/COLOR] Gr.DrawImage(OrigBitMap, 0, 0) [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]Notice that in the TrackZoom Scroll we have to form the ratio of the previous zoom position to the new zoom position to get the new zoom factor. In the case rotation it is easier since rotation is additive.VB Code:
[FONT=Courier New] [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] TrackRotation_Scroll([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, _ [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]Handles[/COLOR] TrackRotation.Scroll [COLOR=#007A00]'perform a rotation transformation on the graphics object [/COLOR] RotateImage(g, TrackRotation.Value) [COLOR=#007A00]'show the results [/COLOR] PictureBox1.Image = bm [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub [/COLOR] [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] TrackZoom_Scroll([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, _ [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]Handles[/COLOR] TrackZoom.Scroll [COLOR=#0000FF]Static[/COLOR] oldScaleX [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1 [COLOR=#0000FF]Static[/COLOR] oldScaleY [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1 [COLOR=#0000FF]Dim[/COLOR] ScaleX [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single [/COLOR] [COLOR=#0000FF]Dim[/COLOR] ScaleY [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single [/COLOR] [COLOR=#007A00]'Since all the transformations are cumulative, [/COLOR] [COLOR=#007A00]'we have to keep track of the previous scaling factors [/COLOR] [COLOR=#007A00]'differences in scaling are ratios [/COLOR] [COLOR=#0000FF]If[/COLOR] ChkZoomX.Checked [COLOR=#0000FF]Then [/COLOR] ScaleX = CType(TrackZoom.Value / 100 / oldScaleX, [COLOR=#0000FF]Single[/COLOR]) oldScaleX = CSng(TrackZoom.Value / 100) [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]If [/COLOR] [COLOR=#0000FF]If[/COLOR] ChkZoomY.Checked [COLOR=#0000FF]Then [/COLOR] ScaleY = CType(TrackZoom.Value / 100 / oldScaleY, [COLOR=#0000FF]Single[/COLOR]) oldScaleY = CSng(TrackZoom.Value / 100) [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]If [/COLOR] [COLOR=#007A00]'scale the graphics object and display results [/COLOR] ZoomImage(g, Scalex, Scaley) PictureBox1.Image = bm [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]
Finally, if you want to access the current image simply access the associated bitmap.VB Code:
[FONT=Courier New] [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] Button2_Click([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]_ Handles[/COLOR] Button2.Click [COLOR=#007A00]'How to save transformed image to file here? [/COLOR] PictureBox2.Image = bm [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]




Reply With Quote