本教程展示如何使用LEADTOOLS多188宝金博怎么下载媒体SDK创建一个Windows使用c++应用程序ltmmConvert
控制和其他LEADTOOLS对象将图片转换成视频。
概述 | |
---|---|
总结 | 本教程介绍了如何使用ltmmConvert 对象创建一个视频从多个图像在Windows c++应用程序。 |
完成时间 | 30分钟 |
Visual Studio项目 | 下载教程项目(KB) 21日 |
平台 | Windows API c++应用程序 |
IDE | Visual Studio 2019 |
开发许可 | 下载LEADTOOLS |
试试用另一种语言 |
|
在工作之前创建一个视频从静态图像——Windows c++教程中,完成添加引用和设置一个许可证教程。
开始的一个副本64位Windows API创建的项目添加引用和设置一个许可证教程。如果项目不可用,按照这个教程中的步骤创建它。
为了使用ltmmConvert
对象,LEADTOOLS需要额外的引用。添加所需的多媒体库通过打开预编译头188宝金博怎么下载文件的引用,pch.h
或stdafx.h
根据使用Visual Studio版本,并添加以下行:
/ /添加LEADTOOLS多媒体188宝金博怎么下载引用
# include“C: \ LEADTOOLS22 \ \ ltmm.h包括”
# include“C: \ LEADTOOLS22 \ \ ltmm_Errors.h包括”
/ / x64填词
# pragma评论(自由,“C: \ \ LEADTOOLS22 \ \ Lib \ \ CDLL \ \ x64 \ \ Ltmmx.lib”)
# pragma评论(自由,“C: \ \ LEADTOOLS22 \ \ Lib \ \ CDLL \ \ x64 \ \ ltmmuuidx.lib”)
本教程的代码加载图像文件和执行一些处理之前将它们转换为视频帧,所以下面的引用是必需的:
# pragma评论(自由,“C: \ \ LEADTOOLS22 \ \ Lib \ \ CDLL \ \ x64 \ \ Ltfil_x.lib”)/ /载入图像库
# pragma评论(自由,“C: \ \ LEADTOOLS22 \ \ Lib \ \ CDLL \ \ x64 \ \ Ltimgefx_x.lib”)/ /图像处理库的影响
与项目创建、添加引用,许可,可以开始编码。
下面的步骤是针对Visual Studio 2019;他们可以为其他版本的Visual Studio是不同的。
去解决方案资源管理器并双击资源文件(.rc)。扩大资源树中菜单选项卡,双击菜单资源designer界面中打开它。下面的空项退出项,点击和类型开发出的视频图像。拖动上面的新项目退出。确保项目的IDID_FILE_CREATEVIDEOFROMIMAGES
。
项目的主CPP文件,其中包含的指向()
主窗口函数。导航到开关(wmId)
下面的语句WM_COMMAND
情况下,添加如下所示的新病例。
/ /指向(),在“案例WM_COMMAND:”
开关(wmId)
{
情况下ID_FILE_CREATEVIDEOFROMIMAGES:
/ /初始化COM
CoInitialize(空);
/ /创建视频
GenerateVideo (hWnd);
/ /清理使用的对象
如果(pMediaType)
pMediaType - >释放();
pMediaType =零;
如果(pSampleSource)
pSampleSource - >释放();
pSampleSource =零;
如果(pConvert)
pConvert - >释放();
pConvert =零;
CoUninitialize ();
打破;
/ /把剩下的代码
添加一个新的功能GenerateVideo (HWND HWND)
加载图片和创建一个AVI文件。下面是函数的代码所需的变量和数据类型。上面这段代码可以添加指向
功能:
类型定义龙龙REFERENCE_TIME;
类型定义结构体tagVIDEOINFOHEADER {
矩形rcSource;
矩形rcTarget;
DWORD dwBitRate;
DWORD dwBitErrorRate;
REFERENCE_TIME AvgTimePerFrame;
BITMAPINFOHEADER bmiHeader;
}VIDEOINFOHEADER;
IltmmConvert * pConvert =零;
IltmmSampleSource * pSampleSource =零;
IltmmMediaTypeDisp * pMediaType =零;
无效GenerateVideo (HWND HWND)
{
TCHAR szFolderIn[1024] =文本(”“);/ /输入文件位置
/ /选择输入文件的文件夹
如果(成功! = GetSourceFolder (hWnd, szFolderIn ARRAYSIZE (szFolderIn)))
返回;
TCHAR szFolderSearch[1024] =文本(”“);/ /输入文件搜索和模式位置
_tcscpy_s (szFolderSearch ARRAYSIZE (szFolderSearch) szFolderIn);
_tcscat_s (szFolderSearch ARRAYSIZE (szFolderSearch)文本(“\ \ * . jpg”));
WIN32_FIND_DATAW FindFileData = {0};
处理hFind = FindFirstFile (szFolderSearch &FindFileData);
如果(INVALID_HANDLE_VALUE = = hFind)
{
对话框(hWnd,文本(“没有JPEG文件中找到文件夹”),文本(“LEADTOOLS演示”),MB_ICONERROR);
返回;
}
TCHAR szFileOut[260] =文本(”“);/ /输出文件的名字
/ /选择输出文件的名字
如果(成功! = GetTargetName (0 szFileOut ARRAYSIZE (szFileOut)))
返回;
/ / IltmmConvert * pConvert =零;
CoCreateInstance (CLSID_ltmmConvert NULL, CLSCTX_INPROC_SERVER IID_IltmmConvert, (无效* *)&pConvert);
如果(pConvert !)
返回;
/ / IltmmSampleSource * pSampleSource =零;
CoCreateInstance (CLSID_ltmmSampleSource NULL, CLSCTX_INPROC_SERVER IID_IltmmSampleSource, (无效* *)&pSampleSource);
/ / IltmmMediaTypeDisp * pMediaType =零;
CoCreateInstance (CLSID_ltmmMediaType NULL, CLSCTX_INPROC_SERVER IID_IltmmMediaTypeDisp, (无效* *)&pMediaType);
型型= SysAllocString (ltmmMEDIATYPE_Video);
pMediaType - > put_Type(型);
SysFreeString(型);
= SysAllocString型(ltmmMEDIASUBTYPE_RGB24);
pMediaType - > put_Subtype(型);
SysFreeString(型);
= SysAllocString型(ltmmFORMAT_VideoInfo);
pMediaType - > put_FormatType(型);
SysFreeString(型);
SetVideoCompressor (pConvert);
双framesPerSecond = 1.5;
常量intimageWidth = 1024, imageHeight = 768;
VIDEOINFOHEADER vih = {0};
vih.bmiHeader。biCompression = BI_RGB;
vih.bmiHeader。biBitCount = 24;
vih.bmiHeader。biSize =运算符BITMAPINFOHEADER;
vih.bmiHeader。biWidth = imageWidth;
vih.bmiHeader。biHeight = imageHeight;
vih.bmiHeader。双翼飞机= 1;
intBytesPerLine = ((imageWidth * 3 + 3) / 4) * 4;/ /使用整数除法计算字节填充4字节的倍数
intbmpSize = BytesPerLine * imageHeight;
vih.bmiHeader。biSizeImage = bmpSize;
vih.bmiHeader。biClrImportant = 0;
vih。AvgTimePerFrame = (REFERENCE_TIME) (10000000.0 / framesPerSecond);
vih。字dwBitRate = () (bmpSize * 8 * framesPerSecond);
SAFEARRAY sa = {0};
变量var;
sa。cbElements =运算符(无符号字符);
sa。cDims = 1;
sa。fFeatures = (FADF_AUTO | FADF_FIXEDSIZE);
sa。pvData = &vih;
sa.rgsabound [0]。cElements =运算符vih;
VariantInit (var);
V_VT (var) = (VT_ARRAY | VT_UI1);
V_ARRAY (var) = sa);
pMediaType - > SetFormatData (运算符vih var);
pMediaType - > put_SampleSize (bmpSize);
pMediaType - > put_FixedSizeSamples (VARIANT_TRUE);
/ /分配源媒体类型
pSampleSource - > SetMediaType (pMediaType);
pConvert - > put_SourceObject (pSampleSource);
= SysAllocString型(szFileOut);
pConvert - > put_TargetFile(型);
SysFreeString(型);
pConvert - > put_TargetFormat (ltmmConvert_TargetFormat_Avi);
pConvert - > StartConvert ();
L_UCHAR * buf =新L_UCHAR [bmpSize];
LARGE_INTEGER开始时间;
LARGE_INTEGER stoptime;
LARGE_INTEGER mstarttime;
LARGE_INTEGER mstoptime;
开始时间。QuadPart = 0;
mstarttime。QuadPart = 0;
intn = 1;
做/ /循环所有图片
{
TCHAR szImageFile[1024] =文本(”“);/ /输入文件位置和名称
_tcscpy_s (szImageFile ARRAYSIZE (szImageFile) szFolderIn);
_tcscat_s (szImageFile ARRAYSIZE (szImageFile)、文本(" \ \ "));
_tcscat_s (szImageFile ARRAYSIZE (szImageFile) FindFileData.cFileName);
TCHAR szProgress [1024];
_stprintf_s (szProgress ARRAYSIZE (szProgress)文本(“加载图像数字% d”),n + +);
HDC HDC = GetDC (hWnd);
TextOut (hDC 50 50, szProgress _tcslen (szProgress));
ReleaseDC (hWnd, hDC);
BITMAPHANDLE BmpLoad = {0}, BmpFrame = {0};
/ /调整图像和保持长宽比
L_LoadBitmapResize (szImageFile &BmpLoad,运算符SIZE_NORMAL BITMAPHANDLE 0 imageHeight, 24日,ORDER_BGR,空,空);
/ *
L_LoadBitmap (szImageFile &BmpLoad sizeof BITMAPHANDLE 24, ORDER_BGR, NULL, NULL);
int newWidth = imageHeight * BITMAPWIDTH (&BmpLoad) / BITMAPHEIGHT (&BmpLoad);
L_SizeBitmap (&BmpLoad newWidth、imageHeight SIZE_RESAMPLE);
* /
L_ChangeBitmapViewPerspective (NULL, &BmpLoad运算符BITMAPHANDLE BOTTOM_LEFT);
L_CreateBitmap (&BmpFrame运算符BITMAPHANDLE、TYPE_CONV imageWidth imageHeight 24, ORDER_BGR, NULL, BOTTOM_LEFT, NULL, 0);
L_FillBitmap (&BmpFrame RGB (255、160、220));
L_CombineBitmap (&BmpFrame, (BITMAPWIDTH (&BmpFrame)——BITMAPWIDTH (&BmpLoad)) / 2, 0, BITMAPWIDTH (&BmpLoad) BITMAPHEIGHT (&BmpLoad) &BmpLoad, 0, 0, CB_RAWCOMBINE | CB_OP_ADD | CB_DST_0, 0);
L_FreeBitmap (&BmpLoad);
/ / L_LoadBitmap (FindFileData。ORDER_BGR cFileName &LtBmp, sizeof LtBmp, 24日,空,空);
/ /帧数转换为文本,然后绘制位图
IltmmMediaSampleDisp * pMediaSample =零;
&pMediaSample pSampleSource - > GetSampleBuffer (1000);
L_AccessBitmap (&BmpFrame);
L_GetBitmapRow (&BmpFrame,但0 bmpSize);
L_ReleaseBitmap (&BmpFrame);
L_FreeBitmap (&BmpFrame);
/ /设置时间100纳秒(基于帧率)
stoptime。QuadPart =开始时间。QuadPart + vih.AvgTimePerFrame;
pMediaSample - >设置系统时间(开始时间。HighPart,开始时间。LowPart stoptime。HighPart stoptime.LowPart);
/ /媒体时间等于帧数
mstoptime。QuadPart = mstarttime。QuadPart + 1;
pMediaSample - > SetMediaTime (mstarttime。HighPart mstarttime。LowPart mstoptime。HighPart mstoptime.LowPart);
/ /这是一个同步点
pMediaSample - > put_SyncPoint (VARIANT_TRUE);
/ /设置示例数据
memset (sa) 0运算符sa);
sa。cbElements =运算符(无符号字符);
sa。cDims = 1;
sa。fFeatures = (FADF_AUTO | FADF_FIXEDSIZE);
sa。pvData =缓冲区;
sa.rgsabound [0]。cElements =bmpSize;
V_VT (var) = (VT_ARRAY | VT_UI1);
V_ARRAY (var) = sa);
pMediaSample - > SetData (bmpSize var);
/ /发送样本下游
pMediaSample pSampleSource - > DeliverSample (1000);
/ /调整下一个时间值
开始时间= stoptime;
mstarttime = mstoptime;
/ /释放样品缓冲
pMediaSample - >释放();
}而(FindNextFile (hFind &FindFileData) ! = 0);
删除[]缓冲区;
InvalidateRect (hWnd, NULL,真的);
对话框(hWnd,文本(“完成创建AVI”),文本(“LEADTOOLS演示”),MB_ICONINFORMATION);
pSampleSource - > DeliverEndOfStream (1000);
pConvert - > StopConvert ();
}
添加三个函数命名GetTargetName
,GetSourceFolder
和SetVideoCompressor
以上GenerateVideo
函数,并添加以下代码:
TCHAR * pszFileName L_INT GetTargetName (HWND HWND, DWORD nLen)
{
OPENFILENAME OPENFILENAME = {0};
OpenFileName。lStructSize =运算符OPENFILENAME;
OpenFileName。hwndOwner = hwnd;
OpenFileName。lpstrFilter =文本(“AVI文件\ 0 * .avi \ 0”);
OpenFileName。lpstrFile = pszFileName;
OpenFileName。nMaxFile = nLen;
OpenFileName。lpstrDefExt =文本(“avi”);
OpenFileName。lpstrFileTitle =零;
OpenFileName。nMaxFileTitle = 0;
OpenFileName。lpstrInitialDir =零;
OpenFileName。旗帜= OFN_OVERWRITEPROMPT;
/ /显示文件保存对话框
如果(! GetSaveFileName (&OpenFileName))
返回失败;
返回成功;
}
# include < shobjidl_core.h >
TCHAR * pszFolder L_INT GetSourceFolder (HWND HWND, rsize_t string_size)
{
L_INT nRet =失败;
IFileOpenDialog * pFileOpenDialog =零;
IShellItem * pShellItem =零;
CoCreateInstance (CLSID_FileOpenDialog NULL, CLSCTX_INPROC_SERVER IID_IFileOpenDialog, (无效* *)&pFileOpenDialog);
如果(pFileOpenDialog)
{
pFileOpenDialog - > setoption (FOS_PICKFOLDERS);
如果(成功(pFileOpenDialog - >显示(hWnd)))
{
pFileOpenDialog - > GetResult (&pShellItem);
LPWSTR pFolder =零;
pShellItem - > GetDisplayName (SIGDN_FILESYSPATH &pFolder);
如果(pFolder)
{
_tcscpy_s (pszFolder string_size pFolder);
CoTaskMemFree (pFolder);
nRet =成功;
}
}
}
如果(pShellItem)
pShellItem - >释放();
如果(pFileOpenDialog)
pFileOpenDialog - >释放();
返回nRet;
}
无效SetVideoCompressor (IltmmConvert * pConvert)
{
/ /选择JPEG格式视频压缩和禁用交错,因为它降低了静态图像质量
IltmmCompressors * pCompressors;
pConvert - > get_VideoCompressors (&pCompressors);
长MCMP_MJPEG_CodecIndex = 1;
型型= SysAllocString (L“@device:西南:{33 d9a760 - 90 - c8 - 11 - d0 bd43 - 00 - a0c911ce86} \ \铅MCMP / MJPEG编码(2.0)”);
&MCMP_MJPEG_CodecIndex pCompressors - >找到(型);
SysFreeString(型);
如果(MCMP_MJPEG_CodecIndex > 1)
{
pCompressors - > put_Selection (MCMP_MJPEG_CodecIndex);
IUnknown * pMjpegCodec =零;
pConvert - > GetSubObject (ltmmConvert_Object_VideoCompressor &pMjpegCodec);
IMCMPEncoderOption * pOptions =零;
pMjpegCodec - > QueryInterface (IID_IMCMPEncoderOption, (无效* *)&pOptions);
pMjpegCodec - >释放();
pOptions - > put_Format (FORMAT_MJPEG_411);
pOptions - > put_Flags (FLAGS_INTERLEAVE_NEVER);
pOptions - >释放();
}
pCompressors - >释放();
}
按运行项目F5,或通过选择调试- >开始调试。
如果遵循正确的步骤,应用程序运行并转换所有JPEG图像从一个用户选择视频文件的文件夹。
本教程展示了如何产生一个视频文件从静态图像使用ltmmConvert
对象。