-
Notifications
You must be signed in to change notification settings - Fork 0
/
ScreenBleedHoleStep.cs
77 lines (65 loc) · 3.51 KB
/
ScreenBleedHoleStep.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using WindowsAPI;
using System.Drawing;
using System.Drawing.Imaging;
using System;
using System.Threading.Tasks;
namespace Gotchya
{
/// <summary>
/// Performs an effect that makes the desktop appear that it is bleeding from a hole. Renders every 2nd pixel in checkerboard pattern
/// </summary>
public static class ScreenBleedHoleStep
{
public static void Run(int frames) {
Bitmap screenshot = Desktop.Screenshot();
Bitmap canvas = Desktop.Screenshot();
Mask mask = new Mask(screenshot);
unsafe {
BitmapData screenshotData = screenshot.LockBits(new Rectangle(0, 0, screenshot.Width, screenshot.Height), ImageLockMode.ReadWrite, screenshot.PixelFormat);
int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(screenshot.PixelFormat) / 8;
int heightInPixels = screenshotData.Height;
int widthInBytes = screenshotData.Width * bytesPerPixel;
byte* ptrFirstPixelScreenshot = (byte*)screenshotData.Scan0;
int lastBlue = 255;
int lastGreen = 255;
int lastRed = 255;
int h2 = heightInPixels / 2;
int w2 = widthInBytes / bytesPerPixel / 2;
for (int time = 1; time < frames; time++) {
float scale = time * 10000.0f;
BitmapData canvasData = canvas.LockBits(new Rectangle(0, 0, canvas.Width, canvas.Height), ImageLockMode.ReadWrite, canvas.PixelFormat);
byte* ptrFirstPixelCanvas = (byte*)canvasData.Scan0;
Parallel.For(0, heightInPixels, (y) => {
int yy = y - h2;
byte* currentLineScreenshot = ptrFirstPixelScreenshot + (y * screenshotData.Stride);
byte* currentLineCanvas = ptrFirstPixelCanvas + (y * canvasData.Stride);
int pixelStep = (time + y) % 5;
int startingByte = bytesPerPixel * pixelStep;
for (int xBits = startingByte; xBits < widthInBytes; xBits = xBits + bytesPerPixel * 2) {
int thisBlue = currentLineScreenshot[xBits];
int thisGreen = currentLineScreenshot[xBits + 1];
int thisRed = currentLineScreenshot[xBits + 2];
int x = xBits / bytesPerPixel;
int xx = x - w2;
double factor = 1 * Math.Exp(-(xx * xx / scale) - (yy * yy / scale));
currentLineCanvas[xBits] = (byte)Flattern(lastBlue, thisBlue, factor);
currentLineCanvas[xBits + 1] = (byte)Flattern(lastGreen, thisGreen, factor);
currentLineCanvas[xBits + 2] = (byte)Flattern(lastRed, thisRed, factor);
lastBlue = currentLineScreenshot[xBits];
lastGreen = currentLineScreenshot[xBits + 1];
lastRed = currentLineScreenshot[xBits + 2];
}
});
canvas.UnlockBits(canvasData);
mask.Picture.Image = canvas;
mask.Picture.Update();
}
}
mask.Close();
Mouse.Move(15, Desktop.GetWidth() - 15);
}
private static int Flattern(int oldColor, int newColor, double factor) {
return newColor - (int)(oldColor * factor);
}
}
}