NXPlanetViewCaptureScreenByBlock Method (String, Int32, Int32, Int32, Int32, Int32, Int32, XFrameCaptureBuffereCaptureMode, NXPlanetView, String, XThread) |
Namespace: Pixoneer.NXDL.NXPlanet
public bool CaptureScreenByBlock( string outputPath, int nX1, int nX2, int nY1, int nY2, int nOutNX, int nOutNY, XFrameCaptureBuffereCaptureMode mode, NXPlanetView blockView, out string strErr, XThread thd )
// 메인 PlanetView Window // XAML <Window x:Class="CaptureScreen_WPF.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns : d = "http://schemas.microsoft.com/expression/blend/2008" xmlns : mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns : nxPlanet = "clr-namespace:Pixoneer.NXDL.NXPlanet;assembly=NXPlanet" xmlns : local = "clr-namespace:CaptureScreen_WPF" mc : Ignorable = "d" Title = "MainWindow" Height = "800" Width = "800" Loaded = "Window_Loaded" Closed = "Window_Closed" > <Window.Resources> <nxPlanet:NXPlanetLayer x : Name = "PlanetLayer" x : Key = "KeyPlanetLayer" / > <nxPlanet:NXPlanetLayerComposites x : Name = "PlanetLayerComposite" x : Key = "KeyPlanetLayerComposite" RenderLikeBaseMap = "True" / > < / Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "20" / > <RowDefinition Height = "*" / > < / Grid.RowDefinitions> <Menu Grid.Row = "0"> <MenuItem Header = "열기" x:Name = "menuOpen" Click = "menuOpen_Click" / > <MenuItem Header = "필터링"> <MenuItem Header = "None" x:Name = "menuFilterNone" Click = "menuFilter_Click" / > <MenuItem Header = "Sharpen" x:Name = "menuFilterSharpen" Click = "menuFilter_Click" / > <MenuItem Header = "Basso" x:Name = "menuFilterBasso" Click = "menuFilter_Click" / > < / MenuItem> <MenuItem Header = "화면캡쳐(Visible)" x:Name = "menuCaptureVisible" Click = "menuCaptureVisible_Click" / > <MenuItem Header = "화면캡쳐(Unvisible)" x:Name = "menuCaptureUnvisible" Click = "menuCaptureUnvisible_Click" / > < / Menu> <Grid Grid.Row = "1"> <WindowsFormsHost> <nxPlanet:NXPlanetView x : Name = "PlanetView" / > < / WindowsFormsHost> < / Grid> < / Grid> < / Window> // C# using Microsoft.Win32; using Pixoneer.NXDL; using Pixoneer.NXDL.NGR; using Pixoneer.NXDL.NIO; using Pixoneer.NXDL.NRS; using Pixoneer.NXDL.NXPlanet; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace CaptureScreen_WPF { /// MainWindow.xaml에 대한 상호 작용 논리 public partial class MainWindow : Window { public XRasterIO RasterIO; // 영상의 입출력을 담당할 객체 선언 public XRSLoadFile InputFile; // 입력 영상 public XDMCompManager CompMng = null; // 입력 영상 composite 관리자 public NXPlanetLayerComposites PlanetLayerComposite = null; public string SaveFilePath; // 캡쳐 영상 저장 경로 public MainWindow() { InitializeComponent(); string strError; RasterIO = new XRasterIO(); if (RasterIO.Initialize(out strError) == false) // 영상 입출력 객체 초기화 { MessageBox.Show(strError); } } private void Window_Loaded(object sender, RoutedEventArgs e) { PlanetView.EarthMode = NXPlanetView.eEarthMode.Planet2D; PlanetView.GridType = NXPlanetView.eGridType.GridDegrees; PlanetView.ShowStar = false; PlanetView.ShowGrid = false; PlanetView.ShowStatusInfo = false; PlanetView.ShowPBP = false; PlanetView.Rotatable = true; PlanetView.InverseMouseButton = true; PlanetView.InverseMouseWheel = true; PlanetView.AutoFocus = false; PlanetView.ZoomWheelMode = eViewZoomMode.ZoomStatic; PlanetView.ZoomWheelStaticFactor = 1.0; // Camera 눈의 위치를 보고자 하는 영역 중심으로 설정한다. NXCameraState camState = PlanetView.GetCameraState(); XGeoPoint geoCenter = XGeoPoint.FromDegree(127.2845, 36.3677, 0); if (PlanetView.Planet2DProjection == NXPlanetView.ePlanet2DProjection.WebMercator) { camState.eye = geoCenter.wm; } else { camState.eye = geoCenter.eec; } PlanetView.SetCameraState(camState); // Camera 눈의 위치에서의 Scale(200000) 에 해당하는 카메라 눈의 높이를 계산한다. double alt = PlanetView.GetMapAltitude(200000); // Camera 상태를 눈의 위치와 방위각을 이용해서 설정한다. geoCenter.hgt = alt; PlanetView.SetCameraPosition(geoCenter, XAngle.FromDegree(0)); double maxHeight = PlanetView.GetMapAltitude(50000000); double minHeight = PlanetView.GetMapAltitude(10); PlanetView.MaxZoomIn(true, minHeight); PlanetView.MaxZoomOut(true, maxHeight); if (PlanetView.LayerCount <= 0) { PlanetLayerComposite = FindResource("KeyPlanetLayerComposite") as NXPlanetLayerComposites; NXRenderLayer renderPlanetLayerComposite = PlanetLayerComposite; NXPlanetLayer planetLayer = FindResource("KeyPlanetLayer") as NXPlanetLayer; PlanetView.AddRenderLayer(ref renderPlanetLayerComposite); PlanetView.AddRenderLayer(ref planetLayer); CompMng = PlanetLayerComposite.GetXDMCompManager(); } // PlanetView 의 밝기/대비/채도 설정 // Brightness, Contrast default 값은 1 PlanetView.Brightness = 2.0f; PlanetView.Contrast = 1.5f; PlanetView.Saturation = 0.7f; } private void Window_Closed(object sender, EventArgs e) { if (InputFile != null) InputFile.Dispose(); InputFile = null; Xfn.Close(); } private void menuOpen_Click(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "all file(*.*)|*.*||"; openFileDialog.RestoreDirectory = true; Nullable<bool> result = openFileDialog.ShowDialog(); if (result != true) return; string strFilePath = openFileDialog.FileName; string strError; XRSLoadFile xrsFile = RasterIO.LoadFile(strFilePath, out strError, false, eIOCreateXLDMode.All_NoMsg); if (xrsFile == null) return; ClearView(); AddXDMComposite(xrsFile); if (InputFile != null) { InputFile.Dispose(); InputFile = null; } InputFile = xrsFile; } private void menuFilter_Click(object sender, RoutedEventArgs e) { MenuItem menu = sender as MenuItem; if (menu.Name == "menuFilterNone") { PlanetLayerComposite.SetFilterType(eImageProcessingFilter.None); PlanetLayerComposite.EnableShaderAlgorithm(false); } else if (menu.Name == "menuFilterSharpen") { PlanetLayerComposite.SetFilterType(eImageProcessingFilter.SHARPEN); PlanetLayerComposite.SetFilterSize(7); PlanetLayerComposite.EnableShaderAlgorithm(true); } else if (menu.Name == "menuFilterBasso") { PlanetLayerComposite.SetFilterType(eImageProcessingFilter.BASSO); PlanetLayerComposite.EnableShaderAlgorithm(true); } } // 임시 PlanetView 창 Visible 속성을 true 로 설정한 후 화면 캡쳐 진행 // block 별 도시 및 캡쳐 상황 확인 가능(테스트용) private void menuCaptureVisible_Click(object sender, RoutedEventArgs e) { string saveClipImgName = DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_ffff") + ".xdm"; // 20181107_11_11_11_1111 string saveFolderTemp = AppDomain.CurrentDomain.BaseDirectory.ToString(); // bin/debug SaveFilePath = System.IO.Path.Combine(saveFolderTemp, saveClipImgName); // bin/debug/20181107_11_11_11_1111 int outSizeX = PlanetView.Width * 2; int outSizeY = PlanetView.Height * 2; Win_PlanetViewForCapture winTempView = new Win_PlanetViewForCapture(); winTempView.CaptureEnd += WinTempView_CaptureEnd; winTempView.SetVisibleViewFlag(true); winTempView.CompMng = this.CompMng; winTempView.OutSizeX = outSizeX; winTempView.OutSizeY = outSizeY; winTempView.SaveFilePath = SaveFilePath; winTempView.ViewBrightness = PlanetView.Brightness; winTempView.ViewContrast = PlanetView.Contrast; winTempView.ViewSaturation = PlanetView.Saturation; winTempView.CompositeLayerFilterType = PlanetLayerComposite.GetFilterType(); winTempView.CompositeLayerFilterSize = PlanetLayerComposite.GetFilterSize(); winTempView.ParentPlanetView = PlanetView; winTempView.X1 = 0; winTempView.X2 = PlanetView.Width - 1; winTempView.Y1 = 0; winTempView.Y2 = PlanetView.Height - 1; winTempView.Show(); } // 임시 PlanetView 창 Visible 속성을 false 로 설정한 후 화면 캡쳐 진행 // block 별 도시 및 캡쳐가 Unvisible 상태로 진행됨(권장) private void menuCaptureUnvisible_Click(object sender, RoutedEventArgs e) { string saveClipImgName = DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_ffff") + ".xdm"; // 20181107_11_11_11_1111 string saveFolderTemp = AppDomain.CurrentDomain.BaseDirectory.ToString(); // bin/debug SaveFilePath = System.IO.Path.Combine(saveFolderTemp, saveClipImgName); // bin/debug/20181107_11_11_11_1111 int outSizeX = PlanetView.Width * 2; int outSizeY = PlanetView.Height * 2; Win_PlanetViewForCapture winTempView = new Win_PlanetViewForCapture(); winTempView.CaptureEnd += WinTempView_CaptureEnd; winTempView.SetVisibleViewFlag(false); winTempView.CompMng = this.CompMng; winTempView.OutSizeX = outSizeX; winTempView.OutSizeY = outSizeY; winTempView.SaveFilePath = SaveFilePath; winTempView.ViewBrightness = PlanetView.Brightness; winTempView.ViewContrast = PlanetView.Contrast; winTempView.ViewSaturation = PlanetView.Saturation; winTempView.CompositeLayerFilterType = PlanetLayerComposite.GetFilterType(); winTempView.CompositeLayerFilterSize = PlanetLayerComposite.GetFilterSize(); winTempView.ParentPlanetView = PlanetView; winTempView.X1 = 0; winTempView.X2 = PlanetView.Width - 1; winTempView.Y1 = 0; winTempView.Y2 = PlanetView.Height - 1; winTempView.Show(); } private void ClearView() { PlanetLayerComposite.Lock(); for (int i = 0; i < CompMng.NumComp; i++) { XDMComposite comp = CompMng.GetXDMCompositeAt(i); comp.Dispose(); } CompMng.RemoveXDMCompositeAll(); PlanetLayerComposite.Invalidate(); PlanetLayerComposite.UnLock(); PlanetView.RefreshScreen(); } private void AddXDMComposite(XRSLoadFile xrsFile) { PlanetLayerComposite.Lock(); XDMComposite newComp = new XDMComposite(); int nNumBand = xrsFile.NumBand; if (nNumBand < 3) { XDMBand band = xrsFile.GetBandAt(0); newComp.Mode = eCompMode.Gray; newComp.SetBand(ref band, 0); newComp.SetCutType(eCompCutType.Ct98, 0); newComp.SetStretchCoverage(eCompStretchCoverage.Band, 0); newComp.SetStretchType(eCompStretchType.Linear, 0); } else { XDMBand band1 = xrsFile.GetBandAt(0); XDMBand band2 = xrsFile.GetBandAt(1); XDMBand band3 = xrsFile.GetBandAt(2); newComp.Mode = eCompMode.RGB; newComp.SetBand(ref band3, 0); newComp.SetBand(ref band2, 1); newComp.SetBand(ref band1, 2); for (int i = 0; i < 3; i++) { newComp.SetCutType(eCompCutType.Ct98, i); newComp.SetStretchCoverage(eCompStretchCoverage.Band, i); newComp.SetStretchType(eCompStretchType.Linear, i); } } CompMng.AddXDMComposite(ref newComp); PlanetLayerComposite.ZoomFit(); PlanetLayerComposite.UnLock(); PlanetView.RefreshScreen(); } private void WinTempView_CaptureEnd(object sender, EventArgs e) { if (((CaptureEndEventArgs)e).IsSuccess) { MessageBox.Show(SaveFilePath); } else { MessageBox.Show(((CaptureEndEventArgs)e).Err); } } } } // 임시 PlanetView Window // XAML <Window x:Class="CaptureScreen_WPF.Win_PlanetViewForCapture" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns : d = "http://schemas.microsoft.com/expression/blend/2008" xmlns : mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns : nxPlanet = "clr-namespace:Pixoneer.NXDL.NXPlanet;assembly=NXPlanet" xmlns : local = "clr-namespace:CaptureScreen_WPF" mc : Ignorable = "d" Title = "Win_PlanetViewForCapture" Height = "450" Width = "800" Loaded = "Window_Loaded" Closed = "Window_Closed" IsVisibleChanged = "Window_IsVisibleChanged" > <Window.Resources> <nxPlanet:NXPlanetLayer x : Name = "PlanetLayer" x : Key = "KeyPlanetLayerCapture" OnRender = "PlanetLayer_OnRender" / > <nxPlanet:NXPlanetLayerComposites x : Name = "PlanetLayerComposite" x : Key = "KeyPlanetLayerCompositeCapture" RenderLikeBaseMap = "True" / > < / Window.Resources> <Grid> <WindowsFormsHost> <nxPlanet:NXPlanetView x : Name = "PlanetView" / > < / WindowsFormsHost> < / Grid> < / Window> // C# using Pixoneer.NXDL; using Pixoneer.NXDL.NGR; using Pixoneer.NXDL.NRS; using Pixoneer.NXDL.NXPlanet; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; using static Pixoneer.NXDL.NGR.XFrameCaptureBuffer; namespace CaptureScreen_WPF { /// 캡쳐 대상 PlanetView(ParentPlanetView) 에 도시된 배경지도, 영상을 일정한 block 별로 재도시 후 캡쳐하기 위한 임시 PlanetView /// ParentPlanetView 와 동일한 화면을 만들기 위해서 ParentPlanetView 에 적용된 화질개선 등도 함께 적용해주어야 함 public partial class Win_PlanetViewForCapture : Window { private NXPlanetLayerComposites _planetLayerComposite = null; private Thread _threadCapture = null; private bool _isApplyedEnhance = false; // 화질개선 적용 여부 flag private bool _isRendered = false; // 렌더링 여부 flag private bool _isCaptured = false; // 캡쳐 성공 여부 flag private string _strError = string.Empty; // 캡쳐 실패 에러 메세지 private bool _isVisibleView = true; // 임시 PlanetView 창 보여주기 여부 flag public event EventHandler CaptureEnd; // 캡쳐 종료 이벤트 public XDMCompManager CompMng = null; // ParentPlanetView 에 도시된 영상 public int OutSizeX = 0; // 캡쳐 영상의 X방향 크기 public int OutSizeY = 0; // 캡쳐 영상의 Y방향 크기 public string SaveFilePath = ""; // 캡쳐 영상 저장 경로 // ParentPlanetView 에 적용된 화질개선 적용을 위한 멤버변수 public float ViewBrightness = 1.0f; public float ViewContrast = 1.0f; public float ViewSaturation = 1.0f; public eImageProcessingFilter CompositeLayerFilterType = eImageProcessingFilter.None; public int CompositeLayerFilterSize = 0; // 캡쳐 대상 PlanetView public NXPlanetView ParentPlanetView = null; // 캡쳐 영역(ParentPlanetView 의 스크린 좌표 영역) public int X1 = 0; public int X2 = 0; public int Y1 = 0; public int Y2 = 0; public Win_PlanetViewForCapture() { InitializeComponent(); } // 현재 창 보여주기 여부 설정 public void SetVisibleViewFlag(bool visible) { _isVisibleView = visible; if (_isVisibleView) { ShowInTaskbar = true; WindowStyle = WindowStyle.SingleBorderWindow; //Background = Brushes.Transparent; AllowsTransparency = false; } else { ShowInTaskbar = false; WindowStyle = WindowStyle.None; Background = Brushes.Transparent; AllowsTransparency = true; } } private void Window_Loaded(object sender, RoutedEventArgs e) { // 256 * 256 block 별로 저장됨 // 256 * 256 초과된 사이즈로 설정 필요 PlanetView.Width = 260; PlanetView.Height = 260; // 캡쳐 대상 PlanetView(ParentPlanetView) 의 설정값과 동일하게 설정 PlanetView.EarthMode = NXPlanetView.eEarthMode.Planet2D; PlanetView.GridType = NXPlanetView.eGridType.GridDegrees; PlanetView.ShowStar = false; PlanetView.ShowGrid = false; PlanetView.ShowStatusInfo = false; PlanetView.ShowPBP = false; PlanetView.Rotatable = true; PlanetView.InverseMouseButton = true; PlanetView.InverseMouseWheel = true; PlanetView.AutoFocus = false; PlanetView.ZoomWheelMode = eViewZoomMode.ZoomStatic; PlanetView.ZoomWheelStaticFactor = 1.0; PlanetView.ForceDraw = true; if (PlanetView.LayerCount <= 0) { _planetLayerComposite = FindResource("KeyPlanetLayerCompositeCapture") as NXPlanetLayerComposites; NXRenderLayer renderPlanetLayerComposite = _planetLayerComposite; NXPlanetLayer planetLayer = FindResource("KeyPlanetLayerCapture") as NXPlanetLayer; PlanetView.AddRenderLayer(ref renderPlanetLayerComposite); PlanetView.AddRenderLayer(ref planetLayer); } // 캡쳐 대상 PlanetView(ParentPlanetView) 에 도시된 영상을 똑같이 도시 if (CompMng != null) { _planetLayerComposite.SetXDMCompManager(ref CompMng); } // 캡쳐 대상 PlanetView(ParentPlanetView) 에 적용된 화질개선 값 적용 PlanetView.Brightness = ViewBrightness; PlanetView.Contrast = ViewContrast; PlanetView.Saturation = ViewSaturation; // 캡쳐 쓰레드 시작 _threadCapture = new Thread(new ThreadStart(Capture)); _threadCapture.Start(); } private void Window_Closed(object sender, EventArgs e) { _threadCapture.Abort(); SendEventCaptureEnd(); // 캡쳐 종료 이벤트 전송 } // 임시 PlanetView에 한번이상 렌더링된 후에 필터링 적용 여부 flag 설정 private bool PlanetLayer_OnRender(object sender, Pixoneer.NXDL.NXPlanet.NXPlanetDrawArgs e) { if (_isRendered == false) { _isRendered = true; } if (_isRendered == true && _isApplyedEnhance == false) { _planetLayerComposite.SetFilterType(CompositeLayerFilterType); _planetLayerComposite.SetFilterSize(CompositeLayerFilterSize); if (CompositeLayerFilterType == eImageProcessingFilter.None) { _planetLayerComposite.EnableShaderAlgorithm(false); } else { _planetLayerComposite.EnableShaderAlgorithm(true); } _isApplyedEnhance = true; } return true; } private void Window_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { if (_isVisibleView == false) // 현재 창 숨기기 { if (this.Visibility == System.Windows.Visibility.Visible) { this.Visibility = Visibility.Hidden; } } } private void Capture() { while (true) { // 렌더링과 화질개선 적용 후에 ParentPlanetView 의 캡쳐 진행 Thread.Sleep(20); if (_isRendered == true && _isApplyedEnhance == true) { _isCaptured = ParentPlanetView.CaptureScreenByBlock(SaveFilePath, X1, X2, Y1, Y2, OutSizeX, OutSizeY, eCaptureMode.BASEMAP, PlanetView, out _strError, null); break; } } // 캡쳐 종료 후 Window close Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate { Close(); })); } private void SendEventCaptureEnd() { if (CaptureEnd != null) { // 캡쳐 성공 여부와 에러 메세지 전송 CaptureEndEventArgs param = new CaptureEndEventArgs(); param.IsSuccess = _isCaptured; param.Err = _strError; CaptureEnd(this, param); } } } // 캡쳐 종료 이벤트 arguments 클래스 public class CaptureEndEventArgs : EventArgs { public bool IsSuccess { get; set; } public string Err { get; set; } } }