直接显示相机旋转 90 度 [英] Direct Show camera rotation 90 degree

查看:91
本文介绍了直接显示相机旋转 90 度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地使用 directshow 从网络摄像头预览和录制图像,但问题是当我在平板电脑上使用该应用程序时,方向与我在 PC 上看到的不一样.是否可以旋转此预览图像?我可以在保存之前旋转从预览中获取的位图图像",但是如果我可以在预览中显示正确的方向,那将对我非常有帮助.

I have successfully use directshow to preview and record an image from webcam, but the problem is when I used the application in the tablet, the orientation is not the same as what I saw in PC. Is there a possibility to rotate this preview image? I can rotate the bitmap 'image' taken from the preview before it is saved, but if I can show the correct orientation in the preview , that would be very helpful for me.

我已经阅读了一些喜欢使用 igraphbuilder、渲染文件等的建议......但由于我不是一个非常有经验的 VB.net 开发人员,我很难理解所有这些概念.我花了很多天只是为了找出不同的代码来使相机捕捉工作.但是现在遇到了方向问题.

I have read through some of the suggestion liked using igraphbuilder, render file and etc.... but since I am not an very experienced VB.net developer, I have a very hard time to understand all these concept. I spend many many days just to find out different code to make the camera capture works. But now came across the orientation problem.

此应用程序将前往第三世界国家以帮助协助医院工作,但我现在被困住了....如果有人可以帮助我弄清楚我该怎么做.我真的很感激....

This application is going to the third world countries to help assist hospital work but I am stuck now.... If anyone can help me to figure out how I can do it. I would be really appreciate....

这是代码的样子,如果有人可以帮助添加一些过滤器,以便我可以在 90 度视图中预览图像.

This is what the code looks like and if anyone can help to add some filter so that I can preview the image in a 90 degree view.

非常感谢!!!!

Imports DirectShowLib
 Imports System
 Imports System.Diagnostics
 Imports System.Drawing
 Imports System.Drawing.Imaging
 Imports System.Runtime.InteropServices
 Imports System.Windows.Forms
 Imports System.Runtime.InteropServices.ComTypes

Public Class Form2

Dim MyPicturesFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)

Dim D As Integer = &H8000
'Dim D As Integer = Convert.ToInt32("0X8000", 16)
Public WM_GRAPHNOTIFY As Integer = D + 1

Dim VideoWindow As IVideoWindow = Nothing
Dim MediaControl As IMediaControl = Nothing
Dim MediaEventEx As IMediaEventEx = Nothing
Dim GraphBuilder As IGraphBuilder = Nothing
Dim CaptureGraphBuilder As ICaptureGraphBuilder2 = Nothing

Enum PlayState
    Stopped
    Paused
    Running
    Init
End Enum
Dim CurrentState As PlayState = PlayState.Stopped

Dim rot As DsROTEntry = Nothing

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
    closeinterfaces()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    CaptureVideo()
    PictureBox1.Visible = True
End Sub

Private Sub CaptureVideo()
    Dim hr As Integer = 0
    Dim sourceFilter As IBaseFilter = Nothing
    Try
        GetInterfaces()

        hr = CaptureGraphBuilder.SetFiltergraph(GraphBuilder) 'Specifies filter graph "graphbuilder" for the capture graph builder "captureGraphBuilder" to use.

        sourceFilter = FindCaptureDevice()

        hr = GraphBuilder.AddFilter(sourceFilter, "Video Capture")

        hr = CaptureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, Nothing, Nothing)

        Marshal.ReleaseComObject(sourceFilter)

        SetupVideoWindow()

        rot = New DsROTEntry(GraphBuilder)

        hr = MediaControl.Run()

        CurrentState = PlayState.Running

    Catch ex As Exception
        MessageBox.Show("An unrecoverable error has occurred.With error : " & ex.ToString)
    End Try
End Sub

Private Sub GetInterfaces()
    Dim hr As Integer = 0
    GraphBuilder = CType(New FilterGraph, IGraphBuilder)
    CaptureGraphBuilder = CType(New CaptureGraphBuilder2, ICaptureGraphBuilder2)
    MediaControl = CType(GraphBuilder, IMediaControl)
    VideoWindow = CType(GraphBuilder, IVideoWindow)
    MediaEventEx = CType(GraphBuilder, IMediaEventEx)
    hr = MediaEventEx.SetNotifyWindow(Me.Handle, WM_GRAPHNOTIFY, IntPtr.Zero) 'This method designates a window as the recipient of messages generated by or sent to the current DirectShow object
End Sub

Public Function FindCaptureDevice() As IBaseFilter

    Dim hr As Integer = 0
    Dim classEnum As IEnumMoniker = Nothing
    Dim moniker As IMoniker() = New IMoniker(0) {}
    Dim source As Object = Nothing
    Dim devEnum As ICreateDevEnum = CType(New CreateDevEnum, ICreateDevEnum)
    hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, classEnum, 0)

    Marshal.ReleaseComObject(devEnum)
    If classEnum Is Nothing Then
        Throw New ApplicationException("No video capture device was detected.\r\n\r\n" & _
                       "This sample requires a video capture device, such as a USB WebCam,\r\n" & _
                       "to be installed and working properly.  The sample will now close.")
    End If
    If classEnum.Next(moniker.Length, moniker, IntPtr.Zero) = 0 Then
        Dim iid As Guid = GetType(IBaseFilter).GUID
        moniker(0).BindToObject(Nothing, Nothing, iid, source)
    Else
        Throw New ApplicationException("Unable to access video capture device!")
    End If
    Marshal.ReleaseComObject(moniker(0))
    Marshal.ReleaseComObject(classEnum)
    Return CType(source, IBaseFilter)
End Function

Public Sub SetupVideoWindow()
    Dim hr As Integer = 0
    'set the video window to be a child of the main window
    'putowner : Sets the owning parent window for the video playback window. 
    hr = VideoWindow.put_Owner(PictureBox1.Handle) 'Me.Handle)
    PictureBox1.Visible = False

    hr = VideoWindow.put_WindowStyle(WindowStyle.Child Or WindowStyle.ClipChildren)

    'Use helper function to position video window in client rect of main application window
    ResizeVideoWindow()

    'Make the video window visible, now that it is properly positioned
    'put_visible : This method changes the visibility of the video window. 
    hr = VideoWindow.put_Visible(OABool.True)

End Sub

Public Sub ResizeVideoWindow()
    'Resize the video preview window to match owner window size
    'left , top , width , height
    If Not (VideoWindow Is Nothing) Then 'if the videopreview is not nothing
        VideoWindow.SetWindowPosition(0, 0, Me.Width, Me.ClientSize.Height)
    End If
End Sub

Public Sub closeinterfaces()
    '//stop previewing data
    If Not (Me.MediaControl Is Nothing) Then
        Me.MediaControl.StopWhenReady()
    End If

    Me.CurrentState = PlayState.Stopped

    '//stop recieving events
    If Not (Me.MediaEventEx Is Nothing) Then
        Me.MediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero)
    End If

    '// Relinquish ownership (IMPORTANT!) of the video window.
    '// Failing to call put_Owner can lead to assert failures within
    '// the video renderer, as it still assumes that it has a valid
    '// parent window.
    If Not (Me.VideoWindow Is Nothing) Then
        Me.VideoWindow.put_Visible(OABool.False)
        Me.VideoWindow.put_Owner(IntPtr.Zero)
    End If

    ' // Remove filter graph from the running object table
    If Not (rot Is Nothing) Then
        rot.Dispose()
        rot = Nothing
    End If

    '// Release DirectShow interfaces
    Marshal.ReleaseComObject(Me.MediaControl) : Me.MediaControl = Nothing
    Marshal.ReleaseComObject(Me.MediaEventEx) : Me.MediaEventEx = Nothing
    Marshal.ReleaseComObject(Me.VideoWindow) : Me.VideoWindow = Nothing
    Marshal.ReleaseComObject(Me.GraphBuilder) : Me.GraphBuilder = Nothing
    Marshal.ReleaseComObject(Me.CaptureGraphBuilder) : Me.CaptureGraphBuilder = Nothing

End Sub

Private Sub btnGrab_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGrab.Click

    GrabImage()
End Sub

Public Sub GrabImage()
    '
    '' Get image from clipboard and convert it to a bitmap
    'Try
    '    MediaControl.Pause()

    '    Clipboard.SetImage(PictureBox1.Image)
    '    '
    '    If Clipboard.ContainsImage Then
    '        PictureBox2.Image = Clipboard.GetImage()
    '    End If
    'Catch
    'End Try
    Try
        MediaControl.Pause()

        Dim bmp As New Bitmap(PictureBox1.Width, PictureBox1.Height)

        Using g As Graphics = Graphics.FromImage(bmp)
            Dim pt As Point = PictureBox1.PointToScreen(New Point(0, 0))
            g.CopyFromScreen(pt.X, pt.Y, 0, 0, bmp.Size)
        End Using
        PictureBox2.Image = bmp
        PictureBox2.Visible = True

        'PictureBox1.Visible = False
    Catch
        MsgBox("error")
    End Try

End Sub

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

Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles BtnSave.Click

    Dim newimage As Image = PictureBox2.Image

    Dim gr As Graphics = Graphics.FromImage(newimage)
    Dim myFontLabels As New Font("Arial", 40)
    Dim myBrushLabels As New SolidBrush(Color.Black)

    Dim FolderBrowser As New FolderBrowserDialog
    If FolderBrowser.ShowDialog = Windows.Forms.DialogResult.OK Then
        Me.lblPath.Text = FolderBrowser.SelectedPath & "\Amytest.bmp"
        MsgBox("msg" & Me.lblPath.Text)

    End If

    'newimage.Save(Me.lblPath.Text, ImageFormat.Jpeg)
    'MsgBox("The picture has been successfully copied and saved")

End Sub

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

    Dim newimage As Image = PictureBox2.Image

    Dim gr As Graphics = Graphics.FromImage(newimage)
    Dim myFontLabels As New Font("Arial", 40)
    Dim myBrushLabels As New SolidBrush(Color.Black)

    Dim _sourcefilename$ = Me.lblPath.Text
    Dim _destinationfilename$ = "C:\test.jpg"
    JpegSaveClass.SaveImage(_sourcefilename, _destinationfilename)

End Sub

推荐答案

DirectShow API 没有内置的视频旋转功能.假设您需要旋转,然后将外部(第三方)转换过滤器插入管道并执行转换.

DirectShow API does not have built in capabilities to rotate video. It is assumed that if you need rotation then an external (third party) transformation filter is inserted into pipeline and perform a transform.

多次讨论,见:

这篇关于直接显示相机旋转 90 度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆