Skip to content

Commit 2053269

Browse files
committed
Merge branch 'dev'
2 parents 623870e + a04c11e commit 2053269

File tree

74 files changed

+1907
-1056
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1907
-1056
lines changed

GifRecorder.sln

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{840C4813
2525
EndProject
2626
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PositioningTest", "Other\PositioningTest\PositioningTest.csproj", "{6204EAEF-C4AA-4005-A369-A8E779205696}"
2727
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenToGif.Tests", "ScreenToGif.Tests\ScreenToGif.Tests.csproj", "{95F33D34-1231-49BA-8EE6-645CC2CE481C}"
29+
EndProject
2830
Global
2931
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3032
Debug|Any CPU = Debug|Any CPU
@@ -105,6 +107,22 @@ Global
105107
{6204EAEF-C4AA-4005-A369-A8E779205696}.Release|x64.Build.0 = Release|Any CPU
106108
{6204EAEF-C4AA-4005-A369-A8E779205696}.Release|x86.ActiveCfg = Release|Any CPU
107109
{6204EAEF-C4AA-4005-A369-A8E779205696}.Release|x86.Build.0 = Release|Any CPU
110+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
111+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|Any CPU.Build.0 = Debug|Any CPU
112+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|ARM.ActiveCfg = Debug|Any CPU
113+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|ARM.Build.0 = Debug|Any CPU
114+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|x64.ActiveCfg = Debug|Any CPU
115+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|x64.Build.0 = Debug|Any CPU
116+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|x86.ActiveCfg = Debug|Any CPU
117+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Debug|x86.Build.0 = Debug|Any CPU
118+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|Any CPU.ActiveCfg = Release|Any CPU
119+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|Any CPU.Build.0 = Release|Any CPU
120+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|ARM.ActiveCfg = Release|Any CPU
121+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|ARM.Build.0 = Release|Any CPU
122+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|x64.ActiveCfg = Release|Any CPU
123+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|x64.Build.0 = Release|Any CPU
124+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|x86.ActiveCfg = Release|Any CPU
125+
{95F33D34-1231-49BA-8EE6-645CC2CE481C}.Release|x86.Build.0 = Release|Any CPU
108126
EndGlobalSection
109127
GlobalSection(SolutionProperties) = preSolution
110128
HideSolutionNode = FALSE
@@ -114,6 +132,7 @@ Global
114132
{8B516DFB-0981-48A2-8A06-35F085C13980} = {13F2A1B9-496A-446E-8B06-776ACAE5CEA4}
115133
{2E037DF4-B0AD-43ED-9B99-4623DDF86F5D} = {840C4813-08E8-42C9-83CB-C0FA8BBBD763}
116134
{6204EAEF-C4AA-4005-A369-A8E779205696} = {13F2A1B9-496A-446E-8B06-776ACAE5CEA4}
135+
{95F33D34-1231-49BA-8EE6-645CC2CE481C} = {840C4813-08E8-42C9-83CB-C0FA8BBBD763}
117136
EndGlobalSection
118137
GlobalSection(ExtensibilityGlobals) = postSolution
119138
SolutionGuid = {E505E312-14B9-49C0-AC18-B3B2FB6C1661}

ScreenToGif.Tests/ImageMethods.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Drawing;
4+
5+
using ScreenToGif.Model;
6+
7+
using Xunit;
8+
9+
namespace ScreenToGif.Tests
10+
{
11+
public class ImageMethods
12+
{
13+
[Fact]
14+
public void CanCalculateDifference()
15+
{
16+
var f1 = new FrameInfo()
17+
{
18+
Path = "./TestData/b1.bmp",
19+
Index = 0
20+
};
21+
22+
var f2 = new FrameInfo()
23+
{
24+
Path = "./TestData/b2.bmp",
25+
Index = 1
26+
};
27+
28+
var diff = ImageUtil.ImageMethods.CalculateDifference(f1, f2);
29+
30+
Assert.Equal(25, diff);
31+
}
32+
}
33+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net48</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
9+
<PackageReference Include="xunit" Version="2.4.1" />
10+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\ScreenToGif\ScreenToGif.csproj" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="TestData\b1.bmp">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
<None Update="TestData\b2.bmp">
25+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
26+
</None>
27+
</ItemGroup>
28+
29+
</Project>

ScreenToGif.Tests/TestData/b1.bmp

659 KB
Binary file not shown.

ScreenToGif.Tests/TestData/b2.bmp

659 KB
Binary file not shown.

ScreenToGif/App.xaml.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,6 @@ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEven
329329

330330
private void App_Exit(object sender, ExitEventArgs e)
331331
{
332-
if (UserSettings.All.DeleteCacheWhenClosing)
333-
StorageUtils.PurgeCache();
334-
335332
try
336333
{
337334
MutexList.RemoveAll();

ScreenToGif/Capture/DirectCachedCapture.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,10 +315,12 @@ public override int CaptureWithCursor(FrameInfo frame)
315315
}
316316

317317
//Copy the captured desktop texture into a staging texture, in order to show the mouse cursor and not make the captured texture dirty with it.
318-
Device.ImmediateContext.CopyResource(BackingTexture, StagingTexture);
318+
if (info.TotalMetadataBufferSize > 0 || info.LastMouseUpdateTime > 0)
319+
Device.ImmediateContext.CopyResource(BackingTexture, StagingTexture);
319320

320321
//Gets the cursor image and merges with the staging texture.
321-
GetCursor(StagingTexture, info, frame);
322+
if (info.LastMouseUpdateTime > 0)
323+
GetCursor(StagingTexture, info, frame);
322324

323325
//Saves the most recent capture time.
324326
LastProcessTime = Math.Max(info.LastPresentTime, info.LastMouseUpdateTime);

ScreenToGif/Capture/DirectImageCapture.cs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
using System.Linq;
44
using System.Runtime.InteropServices;
55
using System.Threading.Tasks;
6+
using System.Windows;
67
using ScreenToGif.Model;
78
using ScreenToGif.Util;
9+
using ScreenToGif.Util.Exceptions;
810
using SharpDX;
911
using SharpDX.Direct3D;
1012
using SharpDX.Direct3D11;
@@ -186,15 +188,15 @@ internal void Initialize()
186188
}
187189
catch (SharpDXException e) when (e.Descriptor == SharpDX.DXGI.ResultCode.Unsupported)
188190
{
189-
throw new NotSupportedException("The Desktop Duplication API is not supported on this computer. If you have multiple graphic cards, try running ScreenToGif on integrated graphics.", e);
191+
throw new GraphicsConfigurationException("The Desktop Duplication API is not supported on this computer.", e);
190192
}
191193
catch (SharpDXException e) when (e.Descriptor == SharpDX.DXGI.ResultCode.InvalidCall)
192194
{
193-
throw new NotSupportedException("The Desktop Duplication API is not supported on this screen. If you have multiple screens, try capturing content on the first one (main screen connected to the integrated video graphics processor).", e);
195+
throw new GraphicsConfigurationException("The Desktop Duplication API is not supported on this screen.", e);
194196
}
195197
catch (SharpDXException e) when (e.Descriptor.NativeApiCode == "E_INVALIDARG")
196198
{
197-
throw new NotSupportedException("Looks like that the Desktop Duplication API is not supported on this screen. If you have multiple screens, try capturing content on the first one (main screen connected to the integrated video graphics processor).", e);
199+
throw new GraphicsConfigurationException("Looks like that the Desktop Duplication API is not supported on this screen.", e);
198200
}
199201
}
200202
}
@@ -398,7 +400,8 @@ public override int Capture(FrameInfo frame)
398400
{
399401
LogWriter.Log(ex, "It was not possible to finish capturing the frame with DirectX.");
400402

401-
OnError.Invoke(ex);
403+
MajorCrashHappened = true;
404+
Application.Current.Dispatcher.Invoke(() => OnError.Invoke(ex));
402405
return FrameCount;
403406
}
404407
finally
@@ -504,10 +507,12 @@ public override int CaptureWithCursor(FrameInfo frame)
504507
}
505508

506509
//Copy the captured desktop texture into a staging texture, in order to show the mouse cursor and not make the captured texture dirty with it.
507-
Device.ImmediateContext.CopyResource(BackingTexture, StagingTexture);
510+
if (info.TotalMetadataBufferSize > 0 || info.LastMouseUpdateTime > 0)
511+
Device.ImmediateContext.CopyResource(BackingTexture, StagingTexture);
508512

509513
//Gets the cursor image and merges with the staging texture.
510-
GetCursor(StagingTexture, info, frame);
514+
if (info.LastMouseUpdateTime > 0)
515+
GetCursor(StagingTexture, info, frame);
511516

512517
//Saves the most recent capture time.
513518
LastProcessTime = Math.Max(info.LastPresentTime, info.LastMouseUpdateTime);
@@ -578,7 +583,7 @@ public override int CaptureWithCursor(FrameInfo frame)
578583
LogWriter.Log(ex, "It was not possible to finish capturing the frame with DirectX.");
579584

580585
MajorCrashHappened = true;
581-
OnError.Invoke(ex);
586+
Application.Current.Dispatcher.Invoke(() => OnError.Invoke(ex));
582587
return FrameCount;
583588
}
584589
finally
@@ -774,8 +779,8 @@ protected internal bool GetCursor(Texture2D screenTexture, OutputDuplicateFrameI
774779

775780
//TODO: In a future version, don't merge the cursor image in here, let the editor do that.
776781
//Saves the position of the cursor, so the editor can add the mouse clicks overlay later.
777-
frame.CursorX = PreviousPosition.Position.X - Left;
778-
frame.CursorY = PreviousPosition.Position.Y - Top;
782+
frame.CursorX = PreviousPosition.Position.X - (Left - OffsetLeft);
783+
frame.CursorY = PreviousPosition.Position.Y - (Top - OffsetTop);
779784

780785
//If the method is supposed to simply the get the cursor shape no shape was loaded before, there's nothing else to do.
781786
//if (CursorShapeBuffer?.Length == 0 || (info.LastPresentTime == 0 && info.LastMouseUpdateTime == 0) || !info.PointerPosition.Visible)
@@ -793,7 +798,7 @@ protected internal bool GetCursor(Texture2D screenTexture, OutputDuplicateFrameI
793798
var rightCut = screenTexture.Description.Width - (frame.CursorX + CursorShapeInfo.Width);
794799
var bottomCut = screenTexture.Description.Height - (frame.CursorY + CursorShapeInfo.Height);
795800

796-
//Adjust the offset, so it's possible to add the highlight correctly later.
801+
//Adjust to the hotspot offset, so it's possible to add the highlight correctly later.
797802
frame.CursorX += CursorShapeInfo.HotSpot.X;
798803
frame.CursorY += CursorShapeInfo.HotSpot.Y;
799804

@@ -993,6 +998,9 @@ internal void DisposeInternal()
993998
{
994999
Device.Dispose();
9951000

1001+
if (MajorCrashHappened)
1002+
return;
1003+
9961004
BackingTexture.Dispose();
9971005
StagingTexture.Dispose();
9981006
DuplicatedOutput.Dispose();

ScreenToGif/Controls/RecorderWindow.cs renamed to ScreenToGif/Controls/BaseRecorder.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.ComponentModel;
1+
using System.ComponentModel;
22
using System.Windows;
33
using System.Windows.Input;
44
using ScreenToGif.Model;
@@ -9,10 +9,11 @@ namespace ScreenToGif.Controls
99
/// <summary>
1010
/// All recorders are derived from this class.
1111
/// </summary>
12-
public class RecorderWindow : Window
12+
public class BaseRecorder : Window
1313
{
14-
public static readonly DependencyProperty StageProperty = DependencyProperty.Register(nameof(Stage), typeof(Stage), typeof(RecorderWindow), new FrameworkPropertyMetadata(Stage.Stopped));
15-
public static readonly DependencyProperty FrameCountProperty = DependencyProperty.Register(nameof(FrameCount), typeof(int), typeof(RecorderWindow), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
14+
public static readonly DependencyProperty StageProperty = DependencyProperty.Register(nameof(Stage), typeof(Stage), typeof(BaseRecorder), new FrameworkPropertyMetadata(Stage.Stopped));
15+
public static readonly DependencyProperty FrameCountProperty = DependencyProperty.Register(nameof(FrameCount), typeof(int), typeof(BaseRecorder), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
16+
public static readonly DependencyProperty HasImpreciseCaptureProperty = DependencyProperty.Register(nameof(HasImpreciseCapture), typeof(bool), typeof(BaseRecorder), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
1617

1718
/// <summary>
1819
/// The actual stage of the recorder.
@@ -37,6 +38,16 @@ public int FrameCount
3738
set => SetValue(FrameCountProperty, value);
3839
}
3940

41+
/// <summary>
42+
/// The frame count of the current recording.
43+
/// </summary>
44+
[Bindable(true), Category("Common"), Description("True if the recorder is unable to capture with precision.")]
45+
public bool HasImpreciseCapture
46+
{
47+
get => (bool)GetValue(HasImpreciseCaptureProperty);
48+
set => SetValue(HasImpreciseCaptureProperty, value);
49+
}
50+
4051
/// <summary>
4152
/// The project information about the current recording.
4253
/// </summary>

0 commit comments

Comments
 (0)