From 9e6d87844a1157d76fdd65d89a54cceb8d9f6188 Mon Sep 17 00:00:00 2001 From: MakesYT <2696703792@qq.com> Date: Thu, 13 Feb 2025 00:18:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E5=A4=A7=E5=B9=85?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E6=88=AA=E5=9B=BE=E5=A4=8D=E5=88=B6=E5=88=B0?= =?UTF-8?q?=E5=89=AA=E8=B4=B4=E6=9D=BF=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core.Window/ClipboardWindow.cs | 19 ++++++- Core/SDKs/Services/IClipboardService.cs | 2 + .../Windows/ScreenCaptureWindow.axaml.cs | 57 +++++++++++-------- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/Core.Window/ClipboardWindow.cs b/Core.Window/ClipboardWindow.cs index 75a2c9d2..0d0f3d1b 100644 --- a/Core.Window/ClipboardWindow.cs +++ b/Core.Window/ClipboardWindow.cs @@ -9,6 +9,7 @@ using Avalonia.Platform; using Avalonia.Threading; using Core.SDKs.Services; +using PluginCore; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -224,7 +225,23 @@ public async Task SetImageAsync(Image image) thread.Start(); return await tcs.Task; } - + [STAThread] + public async Task SetImageAsync(ScreenCaptureResult screenCaptureResult) + { + var tcs = new TaskCompletionSource(); + var thread = new Thread(() => + { + var bitmapSource = BitmapSource.Create( + screenCaptureResult.Info.Width, screenCaptureResult.Info.Height, + 96, 96, + PixelFormats.Bgra32, null, + screenCaptureResult.Bytes, (((int)screenCaptureResult.Info.Width * PixelFormat.Rgba8888.BitsPerPixel + 31) & ~31) >> 3); + Clipboard.SetImage(bitmapSource); + }); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + return await tcs.Task; + } private static T BytesToStructure(byte[] bytes) { var size = Marshal.SizeOf(typeof(T)); diff --git a/Core/SDKs/Services/IClipboardService.cs b/Core/SDKs/Services/IClipboardService.cs index 1444861e..2d403549 100644 --- a/Core/SDKs/Services/IClipboardService.cs +++ b/Core/SDKs/Services/IClipboardService.cs @@ -1,5 +1,6 @@ #region +using PluginCore; using SixLabors.ImageSharp; using Bitmap = Avalonia.Media.Imaging.Bitmap; @@ -16,6 +17,7 @@ public interface IClipboardService Bitmap? GetImage(); bool SetImage(Bitmap image); Task SetImageAsync(Image image); + Task SetImageAsync(ScreenCaptureResult screenCaptureResult); } public enum ClipboardType diff --git a/KitopiaAvalonia/Windows/ScreenCaptureWindow.axaml.cs b/KitopiaAvalonia/Windows/ScreenCaptureWindow.axaml.cs index 6efdb61a..1a0c28e6 100644 --- a/KitopiaAvalonia/Windows/ScreenCaptureWindow.axaml.cs +++ b/KitopiaAvalonia/Windows/ScreenCaptureWindow.axaml.cs @@ -895,6 +895,8 @@ private void FinnishCapture() else if (dragTransformY > 0) cropH = (int)selectBoxHeight; else cropH = (int)selectBoxHeight + (int)dragTransformY; + var x = Math.Max((int)dragTransformX, 0); + var y = Math.Max((int)dragTransformY, 0); if (selectMode) { if (_currentWindowInfo.Hwnd != IntPtr.Zero) @@ -907,8 +909,8 @@ private void FinnishCapture() { selectModeAction.Invoke(new ScreenCaptureInfo() { - X = Math.Max((int)dragTransformX, 0), - Y = Math.Max((int)dragTransformY, 0), + X = x, + Y = y, Width = cropW, Height = cropH, ScreenInfo = _screenCaptureInfo.ScreenInfo @@ -934,27 +936,18 @@ private void FinnishCapture() content.Width = bitmap.PixelSize.Width; content.Height = bitmap.PixelSize.Height; renderTargetBitmap.Render(content); - var boundsHeight = (int)(bitmap.PixelSize.Width * bitmap.PixelSize.Height * 4); - var ptr = Marshal.AllocHGlobal(boundsHeight); - renderTargetBitmap.CopyPixels(new PixelRect(0, 0, bitmap.PixelSize.Width, bitmap.PixelSize.Height), + var bufferSize = cropW * cropH * 4; + var ptr = Marshal.AllocHGlobal(bufferSize); + renderTargetBitmap.CopyPixels(new PixelRect(x, y, cropW, cropH), ptr, - boundsHeight, - (((int)bitmap.PixelSize.Width * PixelFormat.Rgba8888.BitsPerPixel + 31) & ~31) >> 3 + bufferSize, + (((int)cropW * PixelFormat.Rgba8888.BitsPerPixel + 31) & ~31) >> 3 ); - var ys = new byte[boundsHeight]; - Marshal.Copy(ptr, ys, 0, boundsHeight); + var ys = new byte[bufferSize]; + Marshal.Copy(ptr, ys, 0, bufferSize); Marshal.FreeHGlobal(ptr); - var image = SixLabors.ImageSharp.Image.LoadPixelData(ys, bitmap.PixelSize.Width, - bitmap.PixelSize.Height); - //image.SaveAsPng("1.png"); - var clone = image.Clone(e => e.Crop(new Rectangle( - Math.Max((int)dragTransformX, 0), Math.Max((int)dragTransformY, 0), - cropW, cropH))); - image.Dispose(); if (selectBytesMode) { - byte[] d = new byte[cropH*cropW*4]; - clone.CopyPixelDataTo(d); Task.Run(() => { selectBytesModeAction.Invoke(new ScreenCaptureResult() @@ -962,15 +955,17 @@ private void FinnishCapture() Info = new ScreenCaptureInfo() { - X = Math.Max((int)dragTransformX, 0), - Y = Math.Max((int)dragTransformY, 0), + X = x, + Y = y, Width = cropW, Height = cropH, ScreenInfo = _screenCaptureInfo.ScreenInfo }, - Bytes = d + Bytes = ys }); - clone.Dispose(); + }).ContinueWith((e) => + { + GC.Collect(2,GCCollectionMode.Optimized); }); } @@ -978,8 +973,22 @@ private void FinnishCapture() { ServiceManager.Services.GetService() - .SetImageAsync(clone) - .ContinueWith((e) => clone.Dispose()); + .SetImageAsync(new ScreenCaptureResult() + { + Info = new ScreenCaptureInfo() + { + + X = x, + Y = y, + Width = cropW, + Height = cropH, + ScreenInfo = _screenCaptureInfo.ScreenInfo + }, + Bytes = ys + }).ContinueWith((e) => + { + GC.Collect(2,GCCollectionMode.Optimized); + }); } bitmap.Dispose(); renderTargetBitmap.Dispose();