Es posible extraer una porcion de una imagen de un video(*.mp4) en un PictureBox como si le tomasemos una foto pero capturando un area especifica del video con el Picturebox, asi tendriamos los valores de top y left y el tamaño basado en width y heigth.
GRACIAS!!!
Por la forma de expresarte me da la sensacion que no tienes una idea bien formada sobre algunos conceptos básicos de procesamiento de video. Yo tampoco es que sea un especialista en temas relacionados, pero puedo explicarte que aquello a lo que llamas "una imagen de un video" se conoce como fotograma o
frame en Inglés, y la manera más sencilla para extraer fotogramas es utilizando alguna de las varias librerías especializadas para operar con archivos de video, como por ejemplo
FFMediaToolkit que está basada en
FFMPEG (y es la que yo estoy acostumbrado a utilizar para tareas relacionadas):
https://www.nuget.org/packages/FFMediaToolkithttps://github.com/radek-k/FFMediaToolkitPara utilizar
FFMediaToolkit necesitarás descargar también las librerías de
FFMPEG. Léete el
Readme.md del vínculo que he compartido al repositorio de
GitHub donde hallarás una explicación más detallada.
A continuación te muestro un ejemplo para extraer el fotograma que coincida con una marca de tiempo específica de un archivo de video:
Imports System.Drawing.Imaging
Imports System.Reflection
Imports FFMediaToolkit
Imports FFMediaToolkit.Decoding[code]
[code=vbnet]<DebuggerStepThrough>
Public Function GetFrame(videoFilePath As String, timestamp As TimeSpan) As Bitmap
Using
file As MediaFile
= MediaFile.
Open(videoFilePath
)
Dim duration
As TimeSpan
= file.
Video.
Info.
Duration If duration < timestamp Then
Throw New ArgumentException("Video duration is smaller than the specified timestamp.", NameOf(timestamp))
End If
Return ImageDataExtensions.
ImageDataExtensions.
ToBitmap(file.
Video.
GetFrame(timestamp
))
End Using
End Function
Por el momento no conozco una API (de varias que he llegado a examinar) que permita extraer un fotograma tomando como criterio el índice de fotograma en cuestión (quiero decir, que si un video tiene por ejemplo 1.000 fotogramas, indicarle que devuelva el fotograma número 500). Con esta API se puede llegar a hacer pero resultando en un procedimiento muy lento cuanto más grande sea el número del fotograma a extraer:
<DebuggerStepThrough>
Public Function GetFrame(videoFilePath As String, frameNumber As Integer) As Bitmap
Using
file As MediaFile
= MediaFile.
Open(videoFilePath
)
Dim totalFrames
As Integer = file.
Video.
Info.
NumberOfFrames.
Value If totalFrames < frameNumber Then
Throw New ArgumentException("Total number of frames is smaller than the specified frame number.", NameOf(frameNumber))
End If
For i As Integer = 0 To (frameNumber - 1)
Try
Using bmp
As Bitmap
= ImageDataExtensions.
ImageDataExtensions.
ToBitmap(file.
Video.
GetNextFrame()) End Using
Catch ex As Exception
Throw
End Try
Next
Try
Return ImageDataExtensions.
ToBitmap(file.
Video.
GetNextFrame()) Catch ex As Exception
Throw
End Try
End Using
End Function
El código del método "ImageDataExtensions.ToBitmap":
// ***********************************************************************
// Author : ElektroStudios
// Modified : 01-December-2020
// ***********************************************************************
#region Imports
using System;
using System.ComponentModel;
using System.Diagnostics;
#endregion
#region ImageData Extensions
namespace DevCase.ThirdParty.FFMediaToolkit.Extensions.ImageDataExtensions {
/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Contains custom extension methods to use with <see cref="global::FFMediaToolkit.Graphics.ImageData"/> type.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
public static class ImageDataExtensions {
#region Public Extension Methods
/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Converts the source <see cref="global::FFMediaToolkit.Graphics.ImageData"/> to <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
/// <remarks>
/// Original source: <see href="https://github.com/radek-k/FFMediaToolkit#usage-details"/>
/// </remarks>
/// ----------------------------------------------------------------------------------------------------
/// <param name="imageData">
/// The source <see cref="global::FFMediaToolkit.Graphics.ImageData"/>.
/// </param>
/// ----------------------------------------------------------------------------------------------------
/// <returns>
/// The resulting <see cref="System.Drawing.Bitmap"/>
/// </returns>
/// ----------------------------------------------------------------------------------------------------
[DebuggerStepThrough]
[EditorBrowsable(EditorBrowsableState.Always)]
public static unsafe System.Drawing.Bitmap ToBitmap(this global::FFMediaToolkit.Graphics.ImageData imageData) {
fixed (byte* data = imageData.Data) {
return new System.Drawing.Bitmap(imageData
.ImageSize.Width, imageData
.ImageSize.Height, imageData
.Stride,
System.Drawing.Imaging.PixelFormat.Format24bppRgb,
new IntPtr
(data
)); }
}
#endregion
}
}
#endregion
asi tendriamos los valores de top y left y el tamaño basado en width y heigth.
No entiendo exactamente que quieres representar en el PictureBox, pero el tamaño del frame / video es el mismo tamaño del objeto Bitmap (Bitmap.Size) devuelto por la función "GetFrame".
Saludos.[/code][/code]