Skip to content

Commit 8ff9fa0

Browse files
authored
Merge pull request #3 from cmksoftdev/png_support
Png support
2 parents 945c244 + 4ca1b4f commit 8ff9fa0

File tree

9 files changed

+375
-55
lines changed

9 files changed

+375
-55
lines changed

GifRecorder/GifRecorder.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,15 @@
8989
<SubType>Designer</SubType>
9090
</ApplicationDefinition>
9191
<Compile Include="Models\DpiContainer.cs" />
92+
<Compile Include="Models\SizeOffset.cs" />
9293
<Compile Include="Resource.Designer.cs">
9394
<AutoGen>True</AutoGen>
9495
<DesignTime>True</DesignTime>
9596
<DependentUpon>Resource.resx</DependentUpon>
9697
</Compile>
98+
<Compile Include="Services\CrcCalculator.cs" />
9799
<Compile Include="Services\DpiGetter.cs" />
100+
<Compile Include="Services\ImageChangeAnalyser.cs" />
98101
<Compile Include="Services\PngWriter.cs" />
99102
<Compile Include="Views\SectionView.xaml.cs">
100103
<DependentUpon>SectionView.xaml</DependentUpon>

GifRecorder/Models/SizeOffset.cs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace GifRecorder.Models
8+
{
9+
public class SizeOffset
10+
{
11+
public int SizeX;
12+
public int SizeY;
13+
public int OffsetX;
14+
public int OffsetY;
15+
}
16+
}

GifRecorder/Services/CrcCalculator.cs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace GifRecorder.Services
8+
{
9+
public class CrcCalculator
10+
{
11+
long[] pTable = new long[256];
12+
13+
//Für Standard CRC32:
14+
//(Wert kann verändert werden)
15+
long Poly = 0xEDB88320;
16+
17+
public CrcCalculator()
18+
{
19+
long CRC;
20+
int i, j;
21+
22+
for (i = 0; i < 256; i++)
23+
{
24+
CRC = i;
25+
26+
for (j = 0; j < 8; j++)
27+
{
28+
if ((CRC & 0x1) == 1)
29+
{
30+
CRC = (CRC >> 1) ^ Poly;
31+
}
32+
else
33+
{
34+
CRC = (CRC >> 1);
35+
}
36+
}
37+
pTable[i] = CRC;
38+
}
39+
40+
}
41+
42+
public uint GetCRC32(byte[] input)
43+
{
44+
long StreamLength, CRC;
45+
46+
StreamLength = input.Length;
47+
48+
CRC = 0xFFFFFFFF;
49+
for (int i = 0; i < input.Length; i++)
50+
{
51+
CRC = ((CRC & 0xFFFFFF00) / 0x100) & 0xFFFFFF ^ pTable[input[i] ^ CRC & 0xFF];
52+
}
53+
CRC = (-(CRC)) - 1; // !(CRC)
54+
55+
return (uint)CRC;
56+
}
57+
58+
}
59+
}

GifRecorder/Services/GifRecorder.cs

+53-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Threading.Tasks;
33
using System.IO;
4+
using System.Drawing.Imaging;
45

56
namespace GifRecorder.Services
67
{
@@ -18,9 +19,12 @@ public GifRecorder(Stream stream, Action<int> action)
1819
this.stepAction = action;
1920
}
2021

21-
public async Task Start(int seconds, int ax, int ay, int bx, int by, int timeInterval)
22+
public async Task Start(int seconds, int ax, int ay, int bx, int by, int timeInterval, int format = 1)
2223
{
23-
await this.captureScreenSequence(seconds, ax, ay, bx, by, timeInterval);
24+
if (format==1)
25+
await this.captureScreenSequenceApng(seconds, ax, ay, bx, by, timeInterval);
26+
else
27+
await this.captureScreenSequence(seconds, ax, ay, bx, by, timeInterval);
2428
}
2529

2630
private async Task captureScreenSequence(int seconds, int ax, int ay, int bx, int by, int timeInterval)
@@ -50,5 +54,52 @@ await Task.Delay((int)(time)).ContinueWith( (t) =>
5054
IsRunning = false;
5155
}
5256
}
57+
58+
private async Task captureScreenSequenceApng(int seconds, int ax, int ay, int bx, int by, int timeInterval)
59+
{
60+
using (var pngWriter = new PngWriter(this.stream, bx, by, timeInterval, 0))
61+
{
62+
var imageChangeAnalyser = new ImageChangeAnalyser();
63+
Cancel = false;
64+
IsRunning = true;
65+
var imageCount = seconds * 1000 / timeInterval;
66+
var time = 0L;
67+
this.stepAction.Invoke(3);
68+
for (int i = 0; i < imageCount; i++)
69+
{
70+
if (Cancel)
71+
break;
72+
time = timeInterval - time < 0 ? 0 : timeInterval - time;
73+
await Task.Delay((int)(time)).ContinueWith((t) =>
74+
{
75+
stepAction.Invoke(time == 0 ? 0 : 1);
76+
var time2 = DateTime.Now.Ticks / 10000;
77+
var image = ScreenShotCreator.CaptureScreen(true, ax, ay, bx, by);
78+
if (false)//for later use
79+
{
80+
var changes = imageChangeAnalyser.GetChanges(image);
81+
if (changes.SizeX == 0 || changes.SizeY == 0)
82+
{
83+
changes.SizeX = 2;
84+
changes.SizeY = 2;
85+
changes.OffsetX = changes.OffsetX > 4 ? changes.OffsetX - 2 : 2;
86+
changes.OffsetY = changes.OffsetY > 4 ? changes.OffsetY - 2 : 2;
87+
}
88+
var newImage = imageChangeAnalyser.GetPartialImage(image, changes);
89+
pngWriter.WriteFrame(newImage, changes.OffsetX, changes.OffsetY);
90+
}
91+
else
92+
{
93+
pngWriter.WriteFrame(image);
94+
}
95+
96+
time = DateTime.Now.Ticks / 10000 - time2;
97+
});
98+
}
99+
this.stepAction.Invoke(-1);
100+
IsRunning = false;
101+
}
102+
this.stream.Close();
103+
}
53104
}
54105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using GifRecorder.Models;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Drawing;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace GifRecorder.Services
10+
{
11+
public class ImageChangeAnalyser
12+
{
13+
private Bitmap oldImage = null;
14+
15+
public SizeOffset GetChanges(Image newImage)
16+
{
17+
var newImageBmp = new Bitmap(newImage);
18+
var x = newImage.Width;
19+
var y = newImage.Height;
20+
var result = new SizeOffset()
21+
{
22+
OffsetX = x,
23+
OffsetY = y,
24+
SizeX = 0,
25+
SizeY = 0
26+
};
27+
var isChanged = false;
28+
if (oldImage != null)
29+
{
30+
for (int i = 0; i < x; i++)
31+
{
32+
for (int j = 0; j < y; j++)
33+
{
34+
Color a = oldImage.GetPixel(i, j);
35+
Color b = newImageBmp.GetPixel(i, j);
36+
if (!isColorEqual(a, b))
37+
{
38+
isChanged = true;
39+
result.OffsetX = i > result.OffsetX ? i : result.OffsetX;
40+
result.OffsetY = j > result.OffsetY ? j : result.OffsetY;
41+
result.SizeX = i < result.SizeX ? i : result.SizeX;
42+
result.SizeY = j < result.SizeY ? j : result.SizeY;
43+
}
44+
}
45+
}
46+
}
47+
48+
oldImage = newImageBmp;
49+
return isChanged ? result : new SizeOffset()
50+
{
51+
OffsetX = 0,
52+
OffsetY = 0,
53+
SizeX = x,
54+
SizeY = y
55+
}; ;
56+
}
57+
58+
public Image GetPartialImage(Image image, SizeOffset sizeOffset)
59+
{
60+
Bitmap original = new Bitmap(image);
61+
Rectangle srcRect = new Rectangle(
62+
sizeOffset.OffsetX,
63+
sizeOffset.OffsetY,
64+
sizeOffset.SizeX,
65+
sizeOffset.SizeY);
66+
return sizeOffset.SizeX == 0 || sizeOffset.SizeY == 0 ?
67+
null : original.Clone(srcRect, original.PixelFormat);
68+
}
69+
70+
private bool isColorEqual(Color a, Color b)
71+
{
72+
return
73+
a.R == b.R &&
74+
a.G == b.G &&
75+
a.B == b.B;
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)