WPF - XDL Tutorial

XDL VideoView 활용 네번째

(piXoneer XDL Tutorial)

 

 

 

 

 

 NXVideoView를 활용하여 동영상 플레이어를 구현해 봅니다.

동영상을 확대/축소, 화면 중심이동, 밝기조절, 회전, Flip,

다양한 필터적용, 화면 캡쳐를 구현해봅니다.

 

 

2019. 04..

 

 

목차

XDL VideoView 활용 네번째... 1

1    사용하기... 1

1.1    메뉴 생성하기... 1

1.2    메뉴에 대한 기능 구현... 1

 

 

 

 

1     사용하기

본 튜터리얼을 공부하기 전에 먼저 XDL VideoView 활용 세번째를 먼저 선행하시기 바랍니다. XDL VideoView 활용 세번째에 이어서 진행합니다.

1.1    메뉴 생성하기

1.1.1     기본으로 생성된 Grid를 두 개의 Row로 나눈 후, 첫 번째 CellMenu를 배치하고 MenuItem 항목을 추가하여 [File] [Open]을 생성한다. (자세한 메뉴생성에 대한 설명은 XDL_VideoView1 Tutorial을 참고한다.)  

 

1.1.2     이어서 오른쪽 버튼을 눌러 MenuItem추가를 한다. 차례로 [View], [Enhance], [Rotate], [Flip], [Shift], [Algor], [Capture]를 추가로 생성한다.

 

 

1.1.3     [View]-[ZoomIn(+)], [View]-[ZoomOut(-)] 기능을 추가한다. [ZoomIn(+)], [ZoomOut(-)] 은 비디오의 뷰 화면을 확대시키거나 축소시키는 기능을 담당한다.

 

 

아래 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_View

 

MenuItem

_ZoomIn(+)

zoomInViewMenuItem

MenuItem

_ZoomOut(-)

zoomOutViewMenuItem

 

 

1.1.4     [Enhance]-[Contrast], [Enhance]-[Brightness], [Enhance]-[Gamma] 기능을 추가한다. “Contrast”, “Brightness”은 각각의 “Contrast”“Brightness”값을 변경시키고, “Gamma”“Gamma”의 인덱스를 변화시켜서 화면의 밝기를 조절하는 기능을 담당한다.

 

 

아래 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_Enhance

 

MenuItem

_Constant 0.2+

constant02EnhanceMenuItem

MenuItem

_Constant 0.2-

constant02Enhance2MenuItem

MenuItem

_Brightness 0.2+

brightness02EnhanceMenuItem

MenuItem

_Brightness 0.2-

brightness02Enhance2MenuItem

MenuItem

_Gamma 0.4

gamma04EnhanceMenuItem

MenuItem

_Gamma 1.0

gamma10EnhanceMenuItem

MenuItem

_Gamma 1.5

gamma15EnhanceMenuItem

MenuItem

_Gamma 2.2

gamma22EnhanceMenuItem

MenuItem

_Gamma 4.0

gamma40EnhanceMenuItem

 

 

1.1.5     [Rotate] 기능을 추가한다. “Rotate”기능은 화면의 회전을 조절하는 기능을 담당한다.

 

 

아래의 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_Rotate

 

MenuItem

_Rotate +45

rotate45RotateMenuItem

MenuItem

_Rotate -45

rotate45Rotate2MenuItem

MenuItem

_Rotate 0

rotate0RotateMenuItem

 

1.1.6     [Flip]-[VFlip], [Flip]-[HFlip] 기능을 추가한다. “Flip”기능은 화면의 좌/(HFlip)나 상/(VFlip) 를 뒤집어서 도시하는 기능을 담당한다.

 

 

아래의 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_Flip

 

MenuItem

_VFlip

vfilpFilpMenuItem

MenuItem

_HFlip

hfilpFilpMenuItem

 

 

1.1.7     [Shift] 기능을 추가한다. “Shift” 기능은 화면을 특정 값만큼 이동시키는 기능을 담당한다.

 

 

Control Type

Header

Name

MenuItem

_Shift

 

MenuItem

_Shift +200, +200

shift200ShiftMenuItem

MenuItem

_Shift -200, -200

shift200Shift2MenuItem

MenuItem

_Shift 0, 0

shift0ShiftMenuItem

 

1.1.8     [Algorithm] 기능을 추가한다.  “Algorithm”기능은 도시되는 동영상에 다양한 필터기능을 적용하는 기능을 담당한다. [Edge Detection], [HDR, Basso], [Median], [Average]필터를 구성한다.

 

 

아래의 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_Algor

 

MenuItem

_Edge Detection

edgedetetionAlgorMenuItem

MenuItem

_HDR

hdrAlgorMenuItem

MenuItem

_Basso

bassoAlgorMenuItem

MenuItem

_Median

medianAlgorMenuItem

MenuItem

_Average

averageAlgorMenuItem

MenuItem

_Disable

disableAlgorMenuItem

 

1.1.9     [Capture] 기능을 추가한다. 현재 도시되는 Frame과 비디오의 첫번째 Frame을 캡쳐해서 저장하는 기능을 구현한다.

 

 

아래의 표를 참고하여 메뉴를 생성한다.

 

Control Type

Header

Name

MenuItem

_Capture

 

MenuItem

_SaveCurrentFrame

saveCurrentFrameCaptureMenuItem

MenuItem

_SaveFrame_FirstFrame

saveFrame_FirstFrameCaptureMenuItem

 

1.2    메뉴에 대한 기능 구현

1.2.1     “View”에 대한 기능을 구현한다. 비디오에 대한 화면 확대/축소에 대한 기능을 구현한다.

// ZoomIn 메뉴 아이템 클릭 시 호출되는 이벤트 함수
private void zoomInViewMenuItem_Click(object sender, RoutedEventArgs e)
{
      XVertex2d VideoScale = nxVideoView1.Scale;

      if (VideoScale.x > 0)
      {
         if (VideoScale.x >= 2.0) return;
      }
      else
      {
         if (VideoScale.x <= -2.0) return;
      }

      if (VideoScale.y > 0)
      {
         if (VideoScale.y >= 2.0) return;
      }

      else
      {
         if (VideoScale.y <= -2.0) return;
      }

      if (VideoScale.x > 0) VideoScale.x += 0.2; else VideoScale.x -= 0.2;
      if (VideoScale.y > 0) VideoScale.y += 0.2; else VideoScale.y -= 0.2;

      nxVideoView1.Scale = VideoScale;
}

// ZoomOut 메뉴 아이템 클릭시 호출되는 이벤트 함수
private void zoomOutViewMenuItem_Click(object sender, RoutedEventArgs e)
{
       XVertex2d VideoScale = nxVideoView1.Scale;

      if (VideoScale.x > 0)
      {
          if (VideoScale.x < 0.5) return;
      }
      else
      {
          if (VideoScale.x > -0.5) return;
      }

      if (VideoScale.y > 0)
      {
          if (VideoScale.y < 0.5) return;
      }
      else
      {
          if (VideoScale.y > -0.5) return;
      }

      if (VideoScale.x > 0) VideoScale.x -= 0.2; else VideoScale.x += 0.2;
      if (VideoScale.y > 0) VideoScale.y -= 0.2; else VideoScale.y += 0.2;

      nxVideoView1.Scale = VideoScale;
}

 

1.2.2     “Rotate”에 대한 기능을 구현한다.

// 재생되고 있는 동영상의 화면을 회전(45도)
private void rotate45RotateMenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Rotation = new XAngle(45);
}

// 재생되고 있는 동영상의 화면을 회전(-45도)
private void rotate45Rotate2MenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Rotation = new XAngle(-45);
}

// 재생되고 있는 동영상의 화면을 회전(0도)
private void rotate0RotateMenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Rotation = new XAngle(0);
}

 

1.2.3     “Enhance”에 대한 기능을 구현한다. 비디오에 대한 화면 밝기 조절에 대한 기능을 구현한다.

// 재생되고 있는 동영상의 Contrast 조절
private void constrast02EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
     nxVideoView1.FilterType = eVideoFilterType.CBS;
     nxVideoView1.Contrast += 0.2f;
}

// 재생되고 있는 동영상의 Contrast 조절
private void constrast02Enhance2MenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.FilterType = eVideoFilterType.CBS;
      nxVideoView1.Contrast -= 0.2f;
}

// 재생되고 있는 동영상의 Brightness 조절
private void brightness02EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.FilterType = eVideoFilterType.CBS;
      nxVideoView1.Brightness += 0.2f;
}

// 재생되고 있는 동영상의 Brightness 조절
private void brightness02Enhance2MenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.FilterType = eVideoFilterType.CBS;
      nxVideoView1.Brightness -= 0.2f;
}

// 재생되고 있는 동영상의 Gamma 조절
private void gamma04EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
nxVideoView1.FilterType = eVideoFilterType.Gamma;
      nxVideoView1.GammaFactor = 0.4f;
}

// 재생되고 있는 동영상의 Gamma 조절
private void gamma10EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
       nxVideoView1.FilterType = eVideoFilterType.Gamma;
       nxVideoView1.GammaFactor = 1.0f;
 }

 // 재생되고 있는 동영상의 Gamma 조절
private void gamma15EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
       nxVideoView1.FilterType = eVideoFilterType.Gamma;
       nxVideoView1.GammaFactor = 1.5f;
}

// 재생되고 있는 동영상의 Gamma 조절
private void gamma22EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
       nxVideoView1.FilterType = eVideoFilterType.Gamma;
       nxVideoView1.GammaFactor = 2.2f;
}

// 재생되고 있는 동영상의 Gamma 조절
private void gamma40EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
       nxVideoView1.FilterType = eVideoFilterType.Gamma;
       nxVideoView1.GammaFactor = 4.0f;
}

 

1.2.4     “Flip”에 대한 기능을 구현한다.

// 동영상 화면을 수직 방향으로 Flip
private void vflipFilpMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x, nxVideoView1.Scale.y * -1);
}

// 동영상 화면을 수평 방향으로 Flip
private void HflipFilpMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x * -1, nxVideoView1.Scale.y);
}

 

1.2.5     비디오 화면 영역 이동(Shift)” 대한 기능을 구현한다.

private void shift200ShiftMenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Translation = new XVertex2d(200, 200);
}

private void shift200Shift2MenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Translation = new XVertex2d(-200, -200);
}

private void shift0ShiftMenuItem_Click(object sender, RoutedEventArgs e)
{
      nxVideoView1.Translation = new XVertex2d(0, 0);
}

 

1.2.6     비디오 영상처리대한 기능을 구현한다.

private void edgeDetectionAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
      // Edge 필터를 설정
      nxVideoView1.FilterType = eVideoFilterType.Edge;
}

private void hdrAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{ 
      // HDR 필터를 설정
      nxVideoView1.FilterType = eVideoFilterType.HDR;
}

 private void bassoAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{ 
       // Basso 필터를 설정
       nxVideoView1.FilterType = eVideoFilterType.Basso;
}

private void medianAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
       // 통해 Median 필터를 설정
       nxVideoView1.FilterType = eVideoFilterType.Median;
}

private void averageAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
       // Average 필터를 설정
       nxVideoView1.FilterType = eVideoFilterType.Average;
}

private void diableAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
       // 필터 설정 해제
       nxVideoView1.FilterType = eVideoFilterType.None;
}

 

1.2.7     비디오 화면 캡쳐에 대한 기능을 구현한다.

// 도시되고 있는 현재 프레임을 저장한다.
private void saveCurrentFrameCaptureMenuItem_Click(object sender, RoutedEventArgs e)
{
      if (VS.video == null)
      {
          MessageBox.Show(this, "동영상을 먼저 Open 하세요.", "오류");
          return;
      }

// 함수 콜 시점의 도시된 영상을 RGB 형식으로 담고 있는 XFramePicture 객체를 생성하여 반환
XFramePicture frameRGB = VS.videoChannel.GetRenderedFrameRGB();

      SaveFileDialog dlg = new SaveFileDialog();
      dlg.Title = "저장 경로를 설정하세요";
      dlg.OverwritePrompt = true;
      dlg.Filter = "JPED File(*.jpg)|*.jpg";
         
      Nullable<bool> result = dlg.ShowDialog();
      if (result == true)
      {
          string strError;
          string strFileName = dlg.FileName;

          // XFramePicture 객체의 화면 프레임을 이미지로 저장
          // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG2000 등 지원
          bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);

          if (!bres)
          {
              MessageBox.Show(this, "프레임 저장에 실패하였습니다.", "오류");
              return;
           }
       }
}

private void saveFrame_FirstFrameCaputreMenuItem_Click(object sender, RoutedEventArgs e)
 {
      if (VS.video == null)
      {
          MessageBox.Show(this, "동영상을 먼저 Open 하세요.", "오류");
          return;
       }

       SaveFileDialog dlg = new SaveFileDialog();
       dlg.Title = "저장 경로를 설정하세요";
       dlg.OverwritePrompt = true;
       dlg.Filter = "JPEG File(*.jpg)|*.jpg";

       Nullable<bool> result = dlg.ShowDialog();
       if (result == true)
       {
           string strError;
           string strFileName = dlg.FileName;

          // XVideoIO 객체를 통해 가져온 동영상 스트림의 첫번째 프레임을 반환
          XFramePicture frameRGB = m_videoIO.GetFirstFrameRGB(VS.videoFilePath, "XFFMPDRIVER", out strError);

          // XFramePucture 객체의 화면 프레임을 이미지로 저장
          // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG200 등 지원
          bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);

          if (!bres)
          {
               MessageBox.Show(this, "프레임 저장에 실패하였습니다.", "오류");
               return;
          }
       }
}

1.2.8     [F5]키를 눌러 프로그램을 실행 후 [View], [Enhance], [Rotate], [Flip], [Algor], [Shift], [Capture] 누르고 하부 기능을 테스트 한다.