1 using System.Diagnostics;
5 * Copyright(c) 2020 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
24 using global::System.ComponentModel;
25 using global::System.Runtime.InteropServices;
26 using global::System.ComponentModel;
27 using Tizen.NUI.BaseComponents;
30 /// Capture snapshots the current scene and save as a file.
31 /// Applications should follow the example below to create capture :
33 /// Capture capture = new Capture();
35 /// If required, you can also subscribe Finished event :
37 /// capture.Finished += onCaptureFinished;
39 /// At the subcribed event handler, user can know whether capture finish succeeded state.
41 /// private void onCaptureFinished(object sender, CaptureFinishedEventArgs e)
43 /// if(e.Success) { //capture success, do something. }
44 /// else { //capture failure, do something. }
47 /// suppose that we want to capture View 'A'. And, the View 'A' is overlapped by another View 'B' that is not a child of 'A'.
48 /// in this case, if source is root of scene, the captured image includes a part of View 'B' on the 'A'.
49 /// however, if source is just View 'A', the result includes only 'A'.
51 [EditorBrowsable(EditorBrowsableState.Never)]
52 public class Capture : BaseHandle
55 /// Create an Capture.
57 [EditorBrowsable(EditorBrowsableState.Never)]
58 public Capture() : this(Interop.Capture.New(), true)
60 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
63 internal Capture(IntPtr cPtr, bool cMemoryOwn) : base(Interop.Capture.Upcast(cPtr), cMemoryOwn)
70 /// <param name="type"></param>
71 [EditorBrowsable(EditorBrowsableState.Never)]
72 protected override void Dispose(DisposeTypes type)
79 if (type == DisposeTypes.Explicit)
82 //Release your own managed resources here.
83 //You should release all of your own disposable objects here.
89 /// This will not be public opened.
90 [EditorBrowsable(EditorBrowsableState.Never)]
91 protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
93 Interop.Capture.Delete(swigCPtr);
97 /// Start capture and save the image as a file.
99 /// <param name="source">source View or Layer to be used for capture.
100 /// This source must be added on the window in advance.</param>
101 /// <param name="position">top-left position of area to be captured.
102 /// this position is defined in the window.</param>
103 /// <param name="size">captured size.</param>
104 /// <param name="path">image file path to be saved as a file.
105 /// If path is empty string, the captured result is not be saved as a file.</param>
106 /// <param name="color">background color of captured scene.</param>
107 /// <exception cref="InvalidOperationException">This exception can be due to the invalid size values, of when width or height is lower than zero.</exception>
108 /// <exception cref="ArgumentNullException">This exception is due to the path is null.</exception>
109 [EditorBrowsable(EditorBrowsableState.Never)]
110 public void Start(Container source, Position position, Size size, string path, Color color )
112 if (size.Width <= 0 || size.Height <=0)
114 throw new InvalidOperationException("size should larger than zero");
116 else if (null == path)
118 throw new ArgumentNullException("path should not be null");
121 if (source is View || source is Layer)
123 Interop.Capture.Start4(swigCPtr, source.SwigCPtr, new Vector2(position.X, position.Y).SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr);
125 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
130 /// Start capture and save the image as a file.
132 /// <param name="source">source View or Layer to be used for capture.
133 /// This source must be added on the window in advance.</param>
134 /// <param name="size">captured size.</param>
135 /// <param name="path">image file path to be saved as a file.
136 /// If path is empty string, the captured result is not be saved as a file.</param>
137 /// <param name="color">background color of captured scene.</param>
138 /// <param name="quality">The value to control image quality for jpeg file format in the range [1, 100].</param>
139 /// <exception cref="InvalidOperationException">This exception can be due to the invalid size values, of when width or height is lower than zero.</exception>
140 /// <exception cref="ArgumentNullException">This exception is due to the path is null.</exception>
141 [EditorBrowsable(EditorBrowsableState.Never)]
142 public void Start(Container source, Size size, string path, Color color, uint quality )
144 if (size.Width <= 0 || size.Height <=0)
146 throw new InvalidOperationException("size should larger than zero");
148 else if (null == path)
150 throw new ArgumentNullException("path should not be null");
152 else if (quality > 100)
154 throw new InvalidOperationException("quality should between 0 to 100");
157 if (source is View || source is Layer)
159 Interop.Capture.Start3(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr, quality);
161 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
166 /// Start capture and save the image as a file.
168 /// <param name="source">source View or Layer to be used for capture.
169 /// This source must be added on the window in advance.</param>
170 /// <param name="size">captured size.</param>
171 /// <param name="path">image file path to be saved as a file.
172 /// If path is empty string, the captured result is not be saved as a file.</param>
173 /// <param name="color">background color of captured scene.</param>
174 /// <exception cref="InvalidOperationException">This exception can be due to the invalid size values, of when width or height is lower than zero.</exception>
175 /// <exception cref="ArgumentNullException">This exception is due to the path is null.</exception>
176 [EditorBrowsable(EditorBrowsableState.Never)]
177 public void Start(Container source, Size size, string path, Color color)
179 if (size.Width <= 0 || size.Height <=0)
181 throw new InvalidOperationException("size should larger than zero");
183 else if (null == path)
185 throw new ArgumentNullException("path should not be null");
188 if (source is View || source is Layer)
190 Interop.Capture.Start1(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr);
192 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
197 /// Start capture and save the image as a file.
200 /// Background color of captured scene is transparent.
202 /// <param name="source">source View or Layer to be used for capture.
203 /// This source must be added on the window in advance.</param>
204 /// <param name="size">captured size.</param>
205 /// <param name="path">image file path to be saved as a file.
206 /// If path is empty string, the captured result is not be saved as a file.</param>
207 /// <exception cref="InvalidOperationException">This exception can be due to the invalid size values, of when width or height is lower than zero.</exception>
208 /// <exception cref="ArgumentNullException">This exception is due to the path is null.</exception>
209 [EditorBrowsable(EditorBrowsableState.Never)]
210 public void Start(Container source, Size size, string path)
212 if (size.Width <= 0 || size.Height <=0)
214 throw new InvalidOperationException("size should larger than zero");
216 else if (null == path)
218 throw new ArgumentNullException("path should not be null");
221 if (source is View || source is Layer)
223 Interop.Capture.Start2(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path);
225 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
230 /// Set result image quality in case of jpeg.
232 /// <param name="quality">quality The value to control image quality for jpeg file format in the range [1, 100]</param>
233 /// <exception cref="InvalidOperationException">This exception can be due to the invalid size values, of when quality is lower than zero or over than 100.</exception>
234 [EditorBrowsable(EditorBrowsableState.Never)]
235 public void SetImageQuality(uint quality)
237 if (quality < 0 || quality > 100)
239 throw new InvalidOperationException("quality should between zero to 100");
242 Interop.Capture.SetImageQuality(swigCPtr, quality);
245 private void onFinished(IntPtr data, int state)
247 if (data != IntPtr.Zero)
249 var arg = new CaptureFinishedEventArgs();
250 // dali native definition :
251 // enum class FinishState
253 // SUCCEEDED, ///< Succeeded in saving the result after capture
254 // FAILED ///< Failed to capture by time out or to save the result
256 arg.Success = (state == 0) ? true : false;
257 finishedEventHandler?.Invoke(this, arg);
261 private CaptureSignal finishedSignal;
262 private delegate void finishedCallbackType(IntPtr data, int state);
263 private finishedCallbackType finishedCallback;
264 private EventHandler<CaptureFinishedEventArgs> finishedEventHandler;
267 /// For subscribing Finished event sent by this class.
269 [EditorBrowsable(EditorBrowsableState.Never)]
270 public event EventHandler<CaptureFinishedEventArgs> Finished
274 if (finishedEventHandler == null && disposed == false)
276 finishedSignal = new CaptureSignal(Interop.Capture.Get(swigCPtr), false);
277 finishedCallback = onFinished;
278 finishedSignal.Connect(finishedCallback);
280 finishedEventHandler += value;
284 finishedEventHandler -= value;
286 if (finishedEventHandler == null && finishedSignal?.Empty() == false)
288 finishedCallback = onFinished;
289 finishedSignal.Disconnect(finishedCallback);
295 /// Get NativeImageSource that is saved captured image.
297 /// <returns>NativeImageSource that is saved captured image.</returns>
298 [EditorBrowsable(EditorBrowsableState.Never)]
299 public NativeImageSource GetNativeImageSource()
301 Tizen.Log.Debug("NUI", $"GetNativeImageSource()");
302 return new NativeImageSource(Interop.Capture.GetNativeImageSourcePtr(swigCPtr), true);
306 /// Generate captured image's Url
308 /// <returns>The Url string representing this captured image source</returns>
309 [EditorBrowsable(EditorBrowsableState.Never)]
310 public string GenerateUrl()
313 url = Interop.Capture.GenerageUrl(swigCPtr);
314 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
321 /// CaptureFinishedEventArgs
323 [EditorBrowsable(EditorBrowsableState.Never)]
324 public class CaptureFinishedEventArgs : EventArgs
327 /// Status of saving the result after capture.
330 /// true when succeeded in saving the result after capture.
331 /// false when failed to capture by time out or to save the result.
333 public bool Success { get; internal set; }
336 internal class CaptureSignal : Disposable
338 internal CaptureSignal(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
342 protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
346 Interop.Capture.DeleteSignal(swigCPtr);
352 bool ret = Interop.Capture.SignalEmpty(swigCPtr);
353 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
357 public uint GetConnectionCount()
359 uint ret = Interop.Capture.SignalGetConnectionCount(swigCPtr);
360 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
364 public void Connect(Delegate func)
366 IntPtr ip = Marshal.GetFunctionPointerForDelegate<Delegate>(func);
368 Interop.Capture.SignalConnect(swigCPtr, new HandleRef(this, ip));
369 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
373 public void Disconnect(Delegate func)
375 IntPtr ip = Marshal.GetFunctionPointerForDelegate<Delegate>(func);
377 Interop.Capture.SignalDisconnect(swigCPtr, new HandleRef(this, ip));
378 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
382 public void Emit(Capture src, bool success)
384 Interop.Capture.SignalEmit(swigCPtr, src.SwigCPtr, (success ? 0 : 1));
385 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();