udkLive

Hello,
I would like to convert a existing code which rotates an image. The code uses some gdi32 calls. I converted the parameters from Long to Integer, from Any to Integer.
Now I'm having trouble with the first API call which is CreateDIBSection call it fails with AccessViolation Exception.
As far as I understand it trys to access a parameter which might not be initalised.
Debugging I see there is only the Structure BITMAPINFO field Bits with "NOTHING" inside - thougt this will be filled from the called CreateDIBSection function. Or do I need to initialize it How
Public Structure BITMAPINFO
Public Header As BITMAPINFOHEADER
Public Bits() As Integer '(Colors)
End Structure
Or did I convert the API call wrong
From: Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Long, pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long
To: Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Integer, ByVal pBitmapInfo As BITMAPINFO, ByVal un As Integer, ByVal lplpVoid As Integer, ByVal handle As Integer, ByVal dw As Integer) As Integer

Thank you in advance for your help

Best regards
udk




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

JohnWein

ByRef pBitmapInfo As BITMAPINFO





Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

ReneeC

Change ALL Longs to Integer - or it will never work.




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

udkLive

Hello,
I converted all calls as suggested - two faults were inside. This solves the access violation problem. The code is executed now but no result picture is generated.
Are there residing more conversion faults in the other API calls Please have a look at the other calls I've converted:

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Integer) As Integer
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Integer, ByVal hBitmap As Integer, ByVal nStartScan As Integer, ByVal nNumScans As Integer, ByRef lpBits As Object, ByRef lpBI As BITMAPINFO, ByVal wUsage As Integer) As Integer
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Integer, ByVal hObject As Integer) As Integer
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Integer) As Integer
Private Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal SrcX As Integer, ByVal SrcY As Integer, ByVal wSrcWidth As Integer, ByVal wSrcHeight As Integer, ByRef lpBits As Object, ByRef lpBitsInfo As BITMAPINFO, ByVal wUsage As Integer, ByVal dwRop As Integer) As Integer
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As Integer, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer
Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Integer, ByRef pBitmapInfo As BITMAPINFO, ByVal un As Integer, ByVal lplpVoid As Integer, ByVal handle As Integer, ByVal dw As Integer) As Integer

Thank you in advance
udk

P.S. here the original declaration from the VB6 original code:
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
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 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 StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long
Private Declare Function BitBlt Lib "gdi32.dll" (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 CreateDIBSection Lib "gdi32" (ByVal hdc As Long, pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long





Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

ReneeC

You know, you can adapt this to .Net. No one is questioning whether or not it will work eventually. But my question is why are you not using System.Drawing which has the same functionality but is managed instead of unmanaged




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

JohnWein

I totally agree with Renee. Either use VB.Net or make a C dll and call it. When you have that may API calls you are penalized by using VB. Rotating an image using .Net is quite easy and there are a number of threads addressing the methods.





Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

Martin Xie - MSFT

Hi udk,

You can rotate an image using System.Drawing instead of P/Invoke GDI32.

The following code sample can rotate an image in a PictureBox control by 90/180/270 degrees.

Prerequisites:

PictureBox1 'used to show image

ComboBox1 'used to provide RotateFlipType

RotateButton 'used to rotate image

SaveButton 'used to save new image

Code Block

Imports System.Drawing

Public Class Form1

'Load image in the PictureBox1 and load items into the ComboBox1.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.PictureBox1.Image = Image.FromFile("E:\VBproject\image.jpg")

Me.ComboBox1.Items.AddRange(System.Enum.GetNames(GetType(RotateFlipType)))

End Sub

'Rotate image

Private Sub RotateButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Me.PictureBox1.Image.RotateFlip(System.Enum.Parse(GetType(RotateFlipType), Me.ComboBox1.SelectedItem.ToString))

Me.PictureBox1.Refresh()

End Sub

'Save new image

Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

Me.PictureBox1.Image.Save("c:\newImage.jpg", Imaging.ImageFormat.Jpeg)

End Sub

End Class

Reference: http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=2227754&SiteID=1

Regards,

Martin






Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

udkLive

Hello,
I need to rotate the image in any requested angle.
Thats why I try to convert old VB6 code. I would prefere a .NET solution. Due to the fact that the conversion I've made is not working I tried it again with VB.NET. Is there a way to rotate a picture in any angle
The VB.NET code I currently have is doing nothing where is the fault

Dim piBoBmp As Bitmap = New Bitmap(myPictureBox.Image)
Dim piBoGraphics As Graphics = Graphics.FromImage(piBoBmp)
piBoGraphics.RotateTransform(CType(myPictureBox.Tag, ImageInfo).angle)
myPictureBox.Image = piBoGraphics.
'myPictureBox.Refresh()

Thank you in advance!
udk




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

ReneeC

Open the object browser and do a search on rotate.

There are about eighth methods there from System. Drawing






Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

JohnWein

"myPictureBox.Image = piBoGraphics." How can you set an Image to a Graphics and do it without error Your code is close but you have to worry about the rotation point. Search TallDude's threads. I think he's big on rotation.





Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

udkLive

Hello John,
yes sorry. The code snippet I took was not compileable.
Around this approach I tried several things to make it work. In this case I tried to assign the "rotated" image back to the picturebox it came from. Hoping this might solve the problem...

I had a look into the object browser there are some methods with rotate. But none of them did it. Maybe I have to setup a pice of code only doing this. To make shure there are no sideeffects (currently my eventhandling is corrupted - I have to click many times onto the picturebox to trigger the concerning events).
Has no one ever rotated an Image not using RotateFlip (angles other than 90, 180, 270 degrees)

Best regards
udk




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

JohnWein

It really didn't take much searching.

Look at jo0ls' code on page 2 of this thread. The basic rotation involes a translation and a rotation.





Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

Martin Xie - MSFT

Hi udk,

The following code sample can rotate an image in any angles using System.Drawing.Drawing2D.Matrix class. Please take it a try.

Prerequisites: PictureBox1 and Button1 on Form1.

Code Block

Imports System.Drawing

Imports System.Drawing.Drawing2D

Imports System.Drawing.Imaging

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'Initialize PictureBox1.Image

Me.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize

Me.PictureBox1.Image = Image.FromFile("E:\VBproject\2.jpg")

End Sub

'Rotate PictureBox1.Image and save the new image.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

Dim map As Bitmap = Me.PictureBox1.Image

'Call Sub and rotate an image by 155 angles.

Dim newImage As Bitmap = RotateImg(map, 155, Color.Transparent) Me.PictureBox1.Image = newImage

newImage.Save("c:\newImage.jpg")

End Sub

Public Shared Function RotateImg(ByVal bmp As Bitmap, ByVal angle As Single, ByVal bkColor As Color) As Bitmap

Dim w As Integer = bmp.Width + 2

Dim h As Integer = bmp.Height + 2

Dim pf As PixelFormat

If bkColor = Color.Transparent Then

pf = PixelFormat.Format32bppArgb

Else

pf = bmp.PixelFormat

End If

Dim tempImg As Bitmap = New Bitmap(w, h, pf)

Dim g As Graphics = Graphics.FromImage(tempImg)

g.Clear(bkColor)

g.DrawImageUnscaled(bmp, 1, 1)

g.Dispose()

Dim path As GraphicsPath = New GraphicsPath()

path.AddRectangle(New RectangleF(0.0F, 0.0F, w, h))

Dim mtrx As Matrix = New Matrix() 'Using System.Drawing.Drawing2D.Matrix class

mtrx.Rotate(angle)

Dim rct As RectangleF = path.GetBounds(mtrx)

Dim newImg As Bitmap = New Bitmap(CInt(Fix(rct.Width)), CInt(Fix(rct.Height)), pf)

g = Graphics.FromImage(newImg)

g.Clear(bkColor)

g.TranslateTransform(-rct.X, -rct.Y)

g.RotateTransform(angle)

g.InterpolationMode = InterpolationMode.HighQualityBilinear

g.DrawImageUnscaled(tempImg, 0, 0)

g.Dispose()

tempImg.Dispose()

Return newImg

End Function

End Class

Best regards,

Martin






Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

udkLive

Hello Martin,
thank you very much!!! This solution solves my problem - although I do not really understand why this has to be done in a not so obvious way. Seems that Microsoft does not really see the need of such a functionality...
Where did you get the knowledge for the needed sequence from Can you advise me a book where I can get such details

Best regards
udk




Re: Visual Basic Express Edition Convert code using gdi32 from VB to VB.NET

Martin Xie - MSFT

Hi udk,

Here is simpler solution.

Input any angles in the TextBox1, then clicking the Button1 will rotate specified image.

Prerequisites: TextBox1 and Button1 on Form1.

Code Block

Public Class Form1

Dim Angle As Integer

Dim img As Image

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

img = Image.FromFile("E:\VBproject\2.jpg")

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Angle = Integer.Parse(TextBox1.Text)

Invalidate() 'Very important

End Sub

Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

Dim M As New Drawing2D.Matrix

Dim PicLocation As New Point(200, 200)

M.RotateAt(Angle, PicLocation)

e.Graphics.Transform = M

e.Graphics.DrawImage(img, PicLocation)

End Sub

End Class

Here are some references:

System.Drawing.Drawing2D.Matrix Class

System.Drawing.Graphics Class
Matrix Transformation of Images in C#, using .NET GDI+

Using Transformations in GDI+ and VB.NET

You can find some books and resources about VB.NET programming.

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=2099704&SiteID=1

Thanks,

Martin