⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vc实现卡拉ok字幕叠加_3.htm

📁 GDI编程的参考资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
              <TBODY>
              <TR>
                <TD align=middle><FONT 
              class=f22><B>VC实现卡拉OK字幕叠加</B></FONT></TD></TR></TBODY></TABLE></TD></TR>
        <TR>
          <TD background=VC实现卡拉OK字幕叠加_3.files/newhard-040906_c_1.gif 
          height=1></TD></TR>
        <TR>
          <TD vAlign=top height=5></TD></TR>
        <TR>
          <TD>
            <TABLE cellSpacing=0 cellPadding=0 width=603 border=0>
              <TBODY>
              <TR>
                <TD vAlign=top align=middle width=373 rowSpan=9>
                  <TABLE cellSpacing=0 cellPadding=0 width=373 align=center 
                  border=0>
                    <TBODY>
                    <TR>
                      <TD align=middle><SPAN id=pip></SPAN></TD></TR>
                    <TR>
                      <TD align=middle><IFRAME 
                        src="VC实现卡拉OK字幕叠加_3.files/y-soft-column-1.htm" 
                        frameBorder=0 width=360 scrolling=no 
                      height=50></IFRAME></TD></TR></TBODY></TABLE></TD>
                <TD width=5></TD>
                <TD vAlign=top width=220>
                  <TABLE cellSpacing=0 cellPadding=0 width=220 border=0>
                    <TBODY>
                    <TR>
                      <TD colSpan=2><FONT class=f21><B>[文章信息]</B></FONT></TD></TR>
                    <TR>
                      <TD colSpan=2 height=10></TD></TR>
                    <TR>
                      <TD vAlign=top width=62>作者:</TD>
                      <TD vAlign=top width=158><FONT 
                      color=#0e3e92>陆其明</FONT></TD></TR>
                    <TR>
                      <TD vAlign=top>时间:</TD>
                      <TD vAlign=top><FONT 
                    color=#0e3e92>2003-11-21</FONT></TD></TR>
                    <TR>
                      <TD vAlign=top>出处:</TD>
                      <TD vAlign=top><FONT color=#0e3e92>VCHelp</FONT></TD></TR>
                    <TR>
                      <TD vAlign=top>责任编辑:</TD>
                      <TD vAlign=top><FONT color=#0e3e92>方舟</FONT></TD></TR>
                    <TR>
                      <TD colSpan=2 height=10></TD></TR></TBODY></TABLE>
                  <TABLE cellSpacing=0 cellPadding=0 width=220 border=0>
                    <TBODY>
                    <TR>
                      <TD colSpan=2><FONT class=f21><B>[文章导读]</B></FONT></TD></TR>
                    <TR>
                      <TD colSpan=2 height=10></TD></TR>
                    <TR>
                      <TD vAlign=top colSpan=2><SPAN 
                        class=f14>本文介绍了卡拉OK字幕叠加的一般原理以及VC上使用GDI的一种简单实现</SPAN></TD></TR>
                    <TR>
                      <TD colSpan=2 height=10></TD></TR></TBODY></TABLE>
                  <SCRIPT 
                  language=JavaScript><!--var ad_id=1003//--></SCRIPT>

                  <SCRIPT language=JavaScript 
                  src="VC实现卡拉OK字幕叠加_3.files/10.js"></SCRIPT>
                </TD>
                <TD width=5></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD>
    <TD width=1 bgColor=#b9bebe rowSpan=13></TD>
    <TD vAlign=top align=middle width=170 bgColor=#ffffff rowSpan=13>
      <TABLE cellSpacing=5 cellPadding=0 width=165 border=0>
        <TBODY>
        <TR>
          <TD align=middle>
            <SCRIPT language=JavaScript><!--var ad_id=0403//--></SCRIPT>

            <SCRIPT language=JavaScript 
            src="VC实现卡拉OK字幕叠加_3.files/04.js"></SCRIPT>
          </TD></TR></TBODY></TABLE>
      <TABLE height=28 cellSpacing=0 cellPadding=0 width=160 
      background=VC实现卡拉OK字幕叠加_3.files/2004-30.gif border=0>
        <TBODY>
        <TR>
          <TD align=middle><B>advertisement</B></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
        <TBODY>
        <TR>
          <TD width=1 bgColor=#adadad></TD>
          <TD align=middle bgColor=#ffffff><SPAN id=sv></SPAN></TD>
          <TD width=1 bgColor=#adadad></TD></TR></TBODY></TABLE>
      <TABLE height=1 cellSpacing=0 cellPadding=0 width=160 bgColor=#adadad 
      border=0>
        <TBODY>
        <TR>
          <TD></TD></TR></TBODY></TABLE>
      <TABLE height=10 cellSpacing=0 cellPadding=0 width=160 border=0>
        <TBODY>
        <TR>
          <TD></TD></TR></TBODY></TABLE>
      <TABLE height=28 cellSpacing=0 cellPadding=0 width=160 
      background=VC实现卡拉OK字幕叠加_3.files/2004-30.gif border=0>
        <TBODY>
        <TR>
          <TD align=middle><B>热点推荐</B></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
        <TBODY>
        <TR>
          <TD width=1 bgColor=#adadad></TD>
          <TD align=middle bgColor=#ffffff>
            <TABLE cellSpacing=0 cellPadding=2 width=150 border=0>
              <TBODY>
              <TR>
                <TD width=7>· </TD>
                <TD width=143><A 
                  href="http://www.yesky.com/SoftChannel/72339069014638592/20041017/1864973.shtml" 
                  target=_blank>天极网软件频道改版调查</A></TD></TR>
              <TR>
                <TD width=7>· </TD>
                <TD width=143><A 
                  href="http://www.yesky.com/SoftChannel/72339069014638592/20041028/1869661.shtml" 
                  target=_blank>10.28软件精选 找乐还是赌钱</A></TD></TR>
              <TR>
                <TD width=7>· </TD>
                <TD width=143><A 
                  href="http://www.yesky.com/SoftChannel/72342389024358400/20041028/1869618.shtml" 
                  target=_blank>中国游戏业——被人们忽视的黑暗</A></TD></TR>
              <TR>
                <TD width=7>· </TD>
                <TD width=143><A 
                  href="http://www.yesky.com/SoftChannel/72356695560421376/20041028/1869602.shtml" 
                  target=_blank>Windows 2000密码破解不完全指南</A></TD></TR>
              <TR>
                <TD width=7>· </TD>
                <TD width=143><A 
                  href="http://www.yesky.com/SoftChannel/72350085605752832/20041028/1869596.shtml" 
                  target=_blank>解决XP SP2带来的网络故障(上)</A></TD></TR></TBODY></TABLE></TD>
          <TD width=1 bgColor=#adadad></TD></TR></TBODY></TABLE>
      <TABLE height=1 cellSpacing=0 cellPadding=0 width=160 bgColor=#adadad 
      border=0>
        <TBODY>
        <TR>
          <TD></TD></TR></TBODY></TABLE></TD>
    <TD width=1 bgColor=#b9bebe rowSpan=13></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#f0f2fb height=5></TD></TR>
  <TR>
    <TD vAlign=top background=VC实现卡拉OK字幕叠加_3.files/newhard-040906_c_1.gif 
    bgColor=#f0f2fb height=1></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#dee2f5>
      <TABLE height=25 cellSpacing=0 cellPadding=0 width=590 align=center 
      border=0>
        <TBODY>
        <TR>
          <TD width=90><FONT class=f21><B>[正文]</B></FONT></TD>
          <TD align=right width=480>
            <P align=right><FONT color=red><A 
            href="http://www.yesky.com/SoftChannel/72342371928702976/20031121/1746826_1.shtml">上一页</A>&nbsp;&nbsp;<A 
            href="http://www.yesky.com/SoftChannel/72342371928702976/20031121/1746826.shtml">1</A> 
            <A 
            href="http://www.yesky.com/SoftChannel/72342371928702976/20031121/1746826_1.shtml">2</A> 
            3 <A 
            href="http://www.yesky.com/SoftChannel/72342371928702976/20031121/1746826_3.shtml">4</A> 
            &nbsp;<A 
            href="http://www.yesky.com/SoftChannel/72342371928702976/20031121/1746826_3.shtml">下一页</A></FONT></P></TD>
          <TD align=middle width=20></TD></TR></TBODY></TABLE></TD></TR>
  <TR>
    <TD vAlign=top background=VC实现卡拉OK字幕叠加_3.files/newhard-040906_c_1.gif 
    bgColor=#f0f2fb height=1></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#f0f2fb height=10></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#f0f2fb>
      <TABLE cellSpacing=0 cellPadding=0 width=590 align=center border=0>
        <TBODY>
        <TR>
          <TD><SPAN class=f14>  <STRONG>三. 
            关键实现<BR></STRONG><BR>  我们使用VC生成一个基于对话框的程序来演示卡拉OK字幕叠加的实现。程序界面如下:<BR><BR><IMG 
            height=174 
            onerror="this.src='http://www.yesky.com/image20010518/85985.jpg';" 
            hspace=3 src="VC实现卡拉OK字幕叠加_3.files/85985.jpg" width=513 align=center 
            vspace=1 border=1><BR>图4 
            演示程序界面<BR><BR>  为了使字幕叠加的过程更加清晰,我们设计了一个逻辑控制类CSubtitleController。在进行真正的字幕叠加之前,我们必须首先调用CSubtitleController类的SetTargetWindow函数设置字幕的显示窗口,随后调用SetSubtitleLine函数设置字幕行的内容、填充时间等属性。具体实现中,我们在主对话框类CKaraokeDemoDlg中定义一个CSubtitleController类的实例mController,并且在对话框的初始化函数OnInitDialog中进行了如下的调用:<BR><BR>BOOL 
            CKaraokeDemoDlg::OnInitDialog() 
            <BR>{<BR>CDialog::OnInitDialog();<BR><BR>// TODO: Add extra 
            initialization 
            here<BR>mController.SetTargetWindow(&amp;mKaraokeWnd);<BR>mController.SetSubtitleLine(mSubtitleArray, 
            mDurationArray, 0, 5);<BR>// ......<BR><BR>return TRUE; 
            <BR>}<BR><BR>  其中,mKaraokeWnd表示字幕显示窗口,是一个CStatic类的对象实例;mSubtitleArray是CString类型的数组,用于存储字幕内容(注意,应将字幕行中的各个字符单独存储);mDurationArray是int类型的数组,用于存储字幕行中各个字符填充需要的时间。mSubtitleArray和mDurationArray可以在CKaraokeDemoDlg类的构造函数中做如下的初始化:<BR><BR>mSubtitleArray 
            = new CString[5];<BR>mDurationArray = new 
            int[5];<BR><BR>mSubtitleArray[0] = "真";<BR>mSubtitleArray[1] = 
            "的";<BR>mSubtitleArray[2] = "好";<BR>mSubtitleArray[3] = 
            "想";<BR>mSubtitleArray[4] = "你";<BR>mDurationArray[0] = 1500; // 
            以毫秒为单位<BR>mDurationArray[1] = 300;<BR>mDurationArray[2] = 
            1600;<BR>mDurationArray[3] = 500;<BR>mDurationArray[4] = 
            1000;<BR><BR>  主对话框类中还使用了一个定时器,定时间隔是40毫秒,即以每秒25帧的频率刷新字幕叠加的进度。我们在开始播放(即当用户按下“Play”按钮)时记下系统时间(存储到DWORD类型的变量mStartTime中),然后在每次定时到达的时候再次读取系统时间,与mStartTime做差值运算,得到当前播放到的时间点(我们暂且称之为流时间)。在定时器消息响应函数CKaraokeDemoDlg::OnTimer中,我们会调用CSubtitleController类的DrawSubtitle函数来完成实际的卡拉OK字幕输出,这个函数的参数就是这个流时间。<BR><BR>  在CSubtitleController类中,我们看到DrawSubtitle函数的具体实现如下:<BR><BR>BOOL 
            CSubtitleController::DrawSubtitle(DWORD 
            inStreamTime)<BR>{<BR>ASSERT(mClientDC);<BR><BR>DWORD timeInChar = 
            0; // 相对于当前字符填充的开始时间的时间<BR>LONG sungLength = 0; // 
            已经唱过的字幕宽度<BR><BR>// LocateChar为CSubtitleController类的一个私有函数<BR>// 
            根据当前播放到的时间点,定位到当前进度中的字符,<BR>// 并且得到播放时间点在当前字符中的相对时间<BR>int 
            currentChar = LocateChar(inStreamTime, timeInChar);<BR>if 
            (currentChar != -1) // 定位成功<BR>{<BR>// 计算已经唱过的字幕宽度<BR>// 
            mFromToArray数组记录各个字符的属性,包括开始、结束时间、尺寸等<BR>sungLength = 
            mFromToArray[currentChar].size.cx * timeInChar;<BR>sungLength = 
            sungLength / mFromToArray[currentChar].duration; <BR>for (int i = 0; 
            i &lt; currentChar; i++)<BR>{<BR>// 
            累加上当前进度中的字符以前的所有字符的宽度<BR>sungLength += 
            mFromToArray[i].size.cx;<BR>}<BR>}<BR>else<BR>{<BR>// 
            如果无法定位到任何一个字符,则画出整行<BR>sungLength = mTotalWidth;<BR>}<BR><BR>// 
            将字幕字体选入目标窗口的DC中<BR>CFont * pOldFont = (CFont *) 
            mClientDC-&gt;SelectObject(&amp;mTextFont);<BR>mClientDC-&gt;SetBkMode(TRANSPARENT); 
            // 设置输出时背景透明<BR><BR>// 生成已经唱过的和尚未唱过的两块窗口区域<BR>// 
            mSungRegion和mSingingRegion均是CRgn类对象实例<BR>mSungRegion.CreateRectRgn(mStartPoint.x, 
            mStartPoint.y, <BR>mStartPoint.x + sungLength, mStartPoint.y + 
            mFromToArray[0].size.cy);<BR>mSingingRegion.CreateRectRgn(mStartPoint.x 
            + sungLength, mStartPoint.y, <BR>mStartPoint.x + mTotalWidth, 
            mStartPoint.y + mFromToArray[0].size.cy);<BR><BR>// 
            画出第一部分:已经唱过的字幕(蓝色填充,白色勾边)<BR>int ret = 
            mClientDC-&gt;SelectClipRgn(&amp;mSungRegion, RGN_COPY); 
            <BR>mClientDC-&gt;SetPolyFillMode(WINDING);<BR>HPEN pOldPen = (HPEN) 
            mClientDC-&gt;SelectObject(mSungBoundaryPen);<BR>HBRUSH pOldBrush = 
            (HBRUSH) 
            mClientDC-&gt;SelectObject(mSungTextBrush);<BR>mClientDC-&gt;BeginPath(); 
            <BR>mClientDC-&gt;TextOut(mStartPoint.x, mStartPoint.y, 
            mSubtitleLine); <BR>mClientDC-&gt;EndPath(); 
            <BR>mClientDC-&gt;StrokeAndFillPath(); // 
            画出字符路径并填充<BR>mClientDC-&gt;SelectClipPath(RGN_AND);<BR>// 
            恢复以前的画笔和画刷<BR>mClientDC-&gt;SelectObject(pOldPen);<BR>mClientDC-&gt;SelectObject(pOldBrush);<BR><BR>// 
            画出第二部分:尚未唱过的字幕(黑色勾边空心字)<BR>pOldPen = (HPEN) 
            mClientDC-&gt;SelectObject(mSingingBoundaryPen);<BR>pOldBrush = 
            (HBRUSH) 
            mClientDC-&gt;SelectObject(mSingingTextBrush);<BR>mClientDC-&gt;SelectClipRgn(&amp;mSingingRegion, 
            RGN_COPY); <BR>mClientDC-&gt;BeginPath(); 
            <BR>mClientDC-&gt;TextOut(mStartPoint.x, mStartPoint.y, 
            mSubtitleLine); 
            <BR>mClientDC-&gt;EndPath();<BR>mClientDC-&gt;StrokePath(); // 
            画出字符路径(不填充)<BR>mClientDC-&gt;SelectClipPath(RGN_AND);<BR>// 
            恢复以前的画笔和画刷<BR>mClientDC-&gt;SelectObject(pOldBrush);<BR>mClientDC-&gt;SelectObject(pOldPen);<BR>mSungRegion.DeleteObject();<BR>mSingingRegion.DeleteObject();<BR><BR>// 
            恢复目标窗口为“全区域”<BR>RECT 
            bounds;<BR>mTargetWnd-&gt;GetClientRect(&amp;bounds);<BR>CRgn 
            rgn;<BR>rgn.CreateRectRgn(bounds.left, bounds.top, bounds.right, 
            bounds.bottom); <BR>ret = mClientDC-&gt;SelectClipRgn(&amp;rgn, 
            RGN_COPY); <BR><BR>// 
            恢复以前的字体<BR>mClientDC-&gt;SelectObject(pOldFont);<BR><BR>// 
            如果无法定位到任何一个字符,则返回一个错误值<BR>return (currentChar != -1);<BR>}<BR><BR>// 
            根据当前播放到的时间点,定位到当前进度中的字符<BR>int CSubtitleController::LocateChar(DWORD 
            inStreamTime, DWORD &amp; outTimeInChar)<BR>{<BR>// 
            mCharCount为整个字幕行的字符个数<BR>for (int i = 0; i &lt; mCharCount; 
            i++)<BR>{<BR>if (inStreamTime &gt;= mFromToArray[i].from &amp;&amp; 
            <BR>inStreamTime &lt; mFromToArray[i].to)<BR>{<BR>outTimeInChar = 
            inStreamTime - mFromToArray[i].from;<BR>return 
            i;<BR>}<BR>}<BR>return 
      -1;<BR>}<BR><BR></SPAN><BR></TD></TR></TBODY></TABLE></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#f0f2fb height=10></TD></TR>
  <TR>
    <TD vAlign=top background=VC实现卡拉OK字幕叠加_3.files/newhard-040906_c_1.gif 
    bgColor=#f0f2fb height=1></TD></TR>
  <TR>
    <TD vAlign=top bgColor=#dee2f5>
      <TABLE height=25 cellSpacing=0 cellPadding=0 width=590 align=center 
      border=0>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -