Article directory
- Preface
- 2. Usage steps
-
- 1.Introduce the assembly
- 2.Introduce classes
- 3.Creation method
- 4. Screen recording code class
- 4. Trampling on pit records
Foreword
This article will record the full screen, select the area and finally convert it to a Gif.
2. Usage steps
1.Introduce assembly
PresentationCore
WindowsBase
2. Introduction of classes
ScreenshotFormView via hyperlink on the right
ScreenHelper View via hyperlink on the right
3.Creation method
/// <summary> /// Compress image quality /// </summary> /// <param name="ImageBefore">Image before compression</param> /// <param name="quality">Quality</param> /// <returns></returns> public static System.IO.MemoryStream CompressImageStream(Image ImageBefore, long quality) {<!-- --> System.Drawing.Imaging.ImageCodecInfo myEncoder = GetEncoder("image/jpeg"); System.Drawing.Imaging.EncoderParameters encoderParameters = new System.Drawing.Imaging.EncoderParameters(1); encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); var memoryStream = new System.IO.MemoryStream(); ImageBefore.Save(memoryStream, myEncoder, encoderParameters); return memoryStream; } /// <summary> /// Compress image quality /// </summary> /// <param name="ImageBefore">Image before compression</param> /// <param name="quality">Quality</param> /// <returns></returns> public static Image CompressImage(Image ImageBefore, long quality) {<!-- --> var stream = CompressImageStream(ImageBefore, quality); return Image.FromStream(stream); } /// <summary> /// Get ImageCodecInfo through mimeType (similar to ContentType) /// </summary> /// <param name="mimeType">Media type (similar to ContentType)</param> /// <returns>ImageCodecInfo</returns> public static System.Drawing.Imaging.ImageCodecInfo GetEncoder(string mimeType) {<!-- --> System.Drawing.Imaging.ImageCodecInfo[] encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); for (int i = 0; i < encoders. Length; i ++ ) {<!-- --> if (encoders[i].MimeType == mimeType) {<!-- --> return encoders[i]; } } return null; }
4. Screen recording code class
code show as below:
/// <summary> /// Record screen /// </summary> public class ScreenRecording {<!-- --> /// <summary> /// Instantiate /// </summary> /// <param name="IsLoop">Whether to set the Gif to loop</param> public ScreenRecording(bool IsLoop = true) {<!-- --> this.IsLoop = IsLoop; } /// <summary> /// Whether the screen is being recorded /// </summary> public bool IsRecording {<!-- --> get; private set; } /// <summary> /// Whether to set the Gif to play in a loop /// </summary> public bool IsLoop {<!-- --> get; set; } /// <summary> /// Screen recording thread /// </summary> Task task {<!-- --> get; set; } #region Gif Actions /// <summary> /// Record Gif pictures /// </summary> /// <param name="flieName">save path</param> /// <param name="quality">Quality (≤0 does not take effect)</param> /// <param name="timeout">Generate a frame of picture every millisecond</param> /// <param name="EndAction">Callback after the gif image is generated</param> /// <returns>Whether screen recording was successfully started</returns> public bool StartRecordingGif(string flieName, long quality = -1, int timeout = 200, Action EndAction = null) {<!-- --> return StartRecordingGif(flieName, quality, timeout, EndAction, ScreenHelper.CopyScreenToImage); } /// <summary> /// Select an area to record Gif pictures /// </summary> /// <param name="flieName">Save path</param> /// <param name="quality">Quality (≤0 does not take effect)</param> /// <param name="timeout">Generate a frame of picture every millisecond</param> /// <param name="EndAction">Callback after the gif image is generated</param> /// <returns>Whether screen recording was successfully started</returns> public bool StartRecordingGifScreen(string flieName, long quality = -1, int timeout = 200, Action EndAction = null) {<!-- --> bool IsRecording = false; ScreenshotForm screenshotForm = new ScreenshotForm(); screenshotForm.ClickSuccessEvent + = () => {<!-- --> if (screenshotForm.Bitmap == null) {<!-- --> return; } IsRecording = StartRecordingGif(flieName, quality, timeout, EndAction, () => ScreenHelper.CopyScreenToImage(screenshotForm.UpperLeftSource, screenshotForm.Bitmap.Size)); }; screenshotForm.ShowDialog(); return IsRecording; } /// <summary> /// Record Gif pictures /// </summary> /// <param name="flieName">Save path</param> /// <param name="quality">Quality (≤0 does not take effect)</param> /// <param name="timeout">Generate a frame of picture every millisecond</param> /// <param name="EndAction">Callback after the gif image is generated</param> /// <param name="ImageFunc">How to generate an image</param> /// <returns>Whether screen recording was successfully started</returns> public bool StartRecordingGif(string flieName, long quality, int timeout, Action EndAction, Func<System.Drawing.Bitmap> ImageFunc) {<!-- --> if(IsRecording) {<!-- --> return false; } IsRecording = true; task = Task.Run(() => {<!-- --> var Gif = new System.Windows.Media.Imaging.GifBitmapEncoder(); while (IsRecording) {<!-- --> System.Threading.Thread.Sleep(timeout); if (!IsRecording) {<!-- --> break; } var img = ImageFunc(); if (quality > 0) {<!-- --> img = (Bitmap)CompressImage(img, quality); } var bmp = img.GetHbitmap(); var src = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( bmp, IntPtr. Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); Gif.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(src)); } if (this. IsLoop) {<!-- --> using (var ms = new MemoryStream()) {<!-- --> Gif. Save(ms); var fileBytes = ms.ToArray(); var applicationExtension = new byte[] {<!-- --> 33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0 , 0 }; var newBytes = new List<byte>(); newBytes.AddRange(fileBytes.Take(13)); newBytes.AddRange(applicationExtension); newBytes.AddRange(fileBytes.Skip(13)); File.WriteAllBytes(flieName, newBytes.ToArray()); } } else {<!-- --> using (FileStream fs = new FileStream(flieName, FileMode.Create)) {<!-- --> Gif. Save(fs); } } if (EndAction != null) {<!-- --> EndAction(); } task = null; }); return true; } /// <summary> /// Stop recording Gif /// </summary> /// <param name="IsWait">Whether to force to wait for the Gif to be generated</param> public void StopRecordingGif(bool IsWait = false) {<!-- --> IsRecording = false; if (task != null & amp; & amp; IsWait) {<!-- --> task.Wait(); } } #endregion }
4. Pitfall records
- The System.Windows.Media.Imaging.GifBitmapEncoder class must be created and used in the same thread during use, otherwise an error will be reported.