Skip to content

Commit cd53658

Browse files
committed
Window mask screenshot support
1 parent 82b8016 commit cd53658

File tree

5 files changed

+197
-66
lines changed

5 files changed

+197
-66
lines changed

Hotkeys.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,12 @@ private ScreenshotTask GetParamteresFromUI()
109109
Color.FromArgb(Convert.ToInt32("FF" + _settings.aeroColorHexBox, 16)),
110110
_settings.mouseCheckbox,
111111
_settings.clearTypeCheckbox,
112-
_settings.shadowCheckbox);
112+
_settings.shadowCheckbox,
113+
_settings.saveActiveDarkCheckbox,
114+
_settings.saveActiveLightCheckbox,
115+
_settings.saveInactiveDarkCheckbox,
116+
_settings.saveInactiveLightCheckbox,
117+
_settings.saveMaskCheckbox);
113118
}
114119
}
115120
}

Main.Designer.cs

Lines changed: 23 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Main.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public MainForm()
6161
saveActiveLightCheckbox.Checked = _settings.saveActiveLightCheckbox;
6262
saveInactiveDarkCheckbox.Checked = _settings.saveInactiveDarkCheckbox;
6363
saveInactiveLightCheckbox.Checked = _settings.saveInactiveLightCheckbox;
64+
saveMaskCheckbox.Checked = _settings.saveMaskCheckbox;
6465

6566
if (!GlassAvailable())
6667
{
@@ -359,11 +360,13 @@ private void OkButtonClick(object sender, EventArgs e)
359360

360361
_registryKey.SetValue("SaveActiveDark", saveActiveDarkCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
361362

362-
_registryKey.SetValue("SaveActiveLight", saveActiveDarkCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
363+
_registryKey.SetValue("SaveActiveLight", saveActiveLightCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
363364

364-
_registryKey.SetValue("SaveInactiveDark", saveActiveDarkCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
365+
_registryKey.SetValue("SaveInactiveDark", saveInactiveDarkCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
365366

366-
_registryKey.SetValue("SaveInactiveLight", saveActiveDarkCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
367+
_registryKey.SetValue("SaveInactiveLight", saveInactiveLightCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
368+
369+
_registryKey.SetValue("SaveMask", saveMaskCheckbox.Checked ? 1 : 0, RegistryValueKind.DWord);
367370

368371
// Save delay settings in an 8-byte long
369372
b = new byte[8];

Screenshot.cs

Lines changed: 148 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,19 @@ public enum BackgroundType
5151
public int ResizeY;
5252
public bool DisableShadow;
5353
public IntPtr WindowHandle;
54+
public bool SaveActiveDark;
55+
public bool SaveActiveLight;
56+
public bool SaveInactiveDark;
57+
public bool SaveInactiveLight;
58+
public bool SaveMask;
5459

5560
public ScreenshotTask(IntPtr window, bool clipboard, string file,
5661
bool resize, int resizeX, int resizeY,
5762
BackgroundType backType, Color backColor,
5863
int checkerSize, bool customGlass, Color aeroColor,
59-
bool mouse, bool clearType, bool shadow)
64+
bool mouse, bool clearType, bool shadow,
65+
bool saveActiveDark, bool saveActiveLight, bool saveInactiveDark,
66+
bool saveInactiveLight, bool saveMask)
6067
{
6168
WindowHandle = window;
6269
ClipboardNotDisk = clipboard;
@@ -72,6 +79,11 @@ public ScreenshotTask(IntPtr window, bool clipboard, string file,
7279
CaptureMouse = mouse;
7380
DisableClearType = clearType;
7481
DisableShadow = shadow;
82+
SaveActiveDark = saveActiveDark;
83+
SaveActiveLight = saveActiveLight;
84+
SaveInactiveDark = saveInactiveDark;
85+
SaveInactiveLight = saveInactiveLight;
86+
SaveMask = saveMask;
7587
}
7688
}
7789

@@ -244,28 +256,46 @@ internal static void CaptureWindow(ref ScreenshotTask data)
244256
string pathInactive = Path.Combine(data.DiskSaveDirectory, name + "_b2.png");
245257
string pathWhiteActive = Path.Combine(data.DiskSaveDirectory, name + "_w1.png");
246258
string pathWhiteInactive = Path.Combine(data.DiskSaveDirectory, name + "_w2.png");
259+
string pathMask = Path.Combine(data.DiskSaveDirectory, name + "_mask.png");
247260

248-
if (File.Exists(pathActive) || File.Exists(pathInactive) || File.Exists(pathWhiteActive) || File.Exists(pathWhiteInactive))
261+
if (File.Exists(pathActive) || File.Exists(pathInactive) || File.Exists(pathWhiteActive) || File.Exists(pathWhiteInactive) || File.Exists(pathMask))
249262
{
250263
for (int i = 1; i < 9999; i++)
251264
{
252265
pathActive = Path.Combine(data.DiskSaveDirectory, name + " " + i + "_b1.png");
253266
pathInactive = Path.Combine(data.DiskSaveDirectory, name + " " + i + "_b2.png");
254267
pathWhiteActive = Path.Combine(data.DiskSaveDirectory, name + " " + i + "_w1.png");
255268
pathWhiteInactive = Path.Combine(data.DiskSaveDirectory, name + " " + i + "_w2.png");
256-
if (!File.Exists(pathActive) && !File.Exists(pathInactive) && !File.Exists(pathWhiteActive) && !File.Exists(pathWhiteInactive))
269+
pathMask = Path.Combine(data.DiskSaveDirectory, name + " " + i + "_mask.png");
270+
if (!File.Exists(pathActive) && !File.Exists(pathInactive) && !File.Exists(pathWhiteActive) && !File.Exists(pathWhiteInactive) && !File.Exists(pathMask))
257271
break;
258272
}
259273
}
260-
s[0].Save(pathActive, ImageFormat.Png);
261-
s[1].Save(pathInactive, ImageFormat.Png);
262-
s[2].Save(pathWhiteActive, ImageFormat.Png);
263-
s[3].Save(pathWhiteInactive, ImageFormat.Png);
264-
}
265-
s[0].Dispose();
266-
s[1].Dispose();
267-
s[2].Dispose();
268-
s[3].Dispose();
274+
if (data.SaveActiveDark)
275+
s[0].Save(pathActive, ImageFormat.Png);
276+
277+
if (data.SaveInactiveDark)
278+
s[1].Save(pathInactive, ImageFormat.Png);
279+
280+
if (data.SaveActiveLight)
281+
s[2].Save(pathWhiteActive, ImageFormat.Png);
282+
283+
if (data.SaveInactiveLight)
284+
s[3].Save(pathWhiteInactive, ImageFormat.Png);
285+
286+
if (data.SaveMask)
287+
s[4].Save(pathMask, ImageFormat.Png);
288+
}
289+
if (s[0] != null)
290+
s[0].Dispose();
291+
if (s[1] != null)
292+
s[1].Dispose();
293+
if (s[2] != null)
294+
s[2].Dispose();
295+
if (s[3] != null)
296+
s[3].Dispose();
297+
if (s[4] != null)
298+
s[4].Dispose();
269299
}
270300

271301
if (data.DoResize)
@@ -424,42 +454,79 @@ private static unsafe Bitmap[] CaptureCompositeScreenshot(ref ScreenshotTask dat
424454
// Capture screenshot with black background
425455
Bitmap blackShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
426456

427-
EmptyForm emptyForm = new EmptyForm();
428-
emptyForm.Show();
429-
//backdrop.Dispose();
430-
backdrop.BackColor = Color.White;
431-
Application.DoEvents();
457+
Bitmap transparentImage;
458+
Bitmap transparentInactiveImage = null;
459+
Bitmap transparentWhiteImage;
460+
Bitmap transparentWhiteInactiveImage = null;
461+
Bitmap transparentMaskImage = null;
432462

433-
// Capture inactive screenshot with white background
434-
emptyForm.Show();
435-
Bitmap whiteInactiveShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
463+
//Capture black mask screenshot
464+
if (data.SaveMask)
465+
{
466+
467+
bool ShadowToggled = false;
468+
if (ShadowEnabled())
469+
{
470+
WindowsApi.SystemParametersInfo(SPI_SETDROPSHADOW, 0, false, 0);
471+
ShadowToggled = true;
472+
}
436473

437-
/*if (data.Background == ScreenshotTask.BackgroundType.SolidColor)
438-
{
439-
backdrop.Dispose();
440-
if (data.CaptureMouse)
441-
DrawCursorToBitmap(whiteShot, new Point(rct.Left, rct.Top));
442-
Bitmap final = CropEmptyEdges(whiteShot, tmpColor);
443-
whiteShot.Dispose();
444-
return final;
445-
}*/
474+
backdrop.BackColor = Color.White;
475+
Application.DoEvents();
476+
Bitmap whiteMaskShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
446477

447-
backdrop.BackColor = Color.Black;
448-
Application.DoEvents();
478+
backdrop.BackColor = Color.Black;
479+
Application.DoEvents();
480+
Bitmap blackMaskShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
449481

450-
// Capture inactive screenshot with black background
451-
emptyForm.Show();
452-
Bitmap blackInactiveShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
482+
transparentMaskImage = CreateMask(DifferentiateAlpha(whiteMaskShot, blackMaskShot, false));
453483

454-
backdrop.Dispose();
484+
if (ShadowToggled)
485+
{
486+
WindowsApi.SystemParametersInfo(SPI_SETDROPSHADOW, 0, true, 0);
487+
}
488+
489+
whiteMaskShot.Dispose();
490+
blackMaskShot.Dispose();
455491

456-
Bitmap transparentImage = DifferentiateAlpha(whiteShot, blackShot, false);
457-
Bitmap transparentInactiveImage = DifferentiateAlpha(whiteInactiveShot, blackInactiveShot, false);
458-
Bitmap transparentWhiteImage = DifferentiateAlpha(whiteShot, blackShot, true);
459-
Bitmap transparentWhiteInactiveImage = DifferentiateAlpha(whiteInactiveShot, blackInactiveShot, true);
492+
}
493+
494+
EmptyForm emptyForm = new EmptyForm();
495+
emptyForm.Show();
496+
//backdrop.Dispose();
497+
498+
// Capture inactive screenshots
499+
if (data.SaveInactiveDark || data.SaveInactiveLight)
500+
{
501+
backdrop.BackColor = Color.White;
502+
Application.DoEvents();
503+
504+
// Capture inactive screenshot with white background
505+
emptyForm.Show();
506+
Bitmap whiteInactiveShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
507+
508+
backdrop.BackColor = Color.Black;
509+
Application.DoEvents();
510+
511+
// Capture inactive screenshot with black background
512+
emptyForm.Show();
513+
Bitmap blackInactiveShot = CaptureScreenRegion(new Rectangle(rct.Left, rct.Top, rct.Right - rct.Left, rct.Bottom - rct.Top));
514+
515+
516+
transparentInactiveImage = DifferentiateAlpha(whiteInactiveShot, blackInactiveShot, false);
517+
transparentWhiteInactiveImage = DifferentiateAlpha(whiteInactiveShot, blackInactiveShot, true);
518+
519+
whiteInactiveShot.Dispose();
520+
blackInactiveShot.Dispose();
521+
}
522+
523+
backdrop.Dispose();
524+
525+
transparentImage = DifferentiateAlpha(whiteShot, blackShot, false);
526+
transparentWhiteImage = DifferentiateAlpha(whiteShot, blackShot, true);
460527
if (data.CaptureMouse)
461528
DrawCursorToBitmap(transparentImage, new Point(rct.Left, rct.Top));
462-
Bitmap[] final = CropEmptyEdges(new[] { transparentImage, transparentInactiveImage, transparentWhiteImage, transparentWhiteInactiveImage }, Color.FromArgb(0, 0, 0, 0));
529+
Bitmap[] final = CropEmptyEdges(new[] { transparentImage, transparentInactiveImage, transparentWhiteImage, transparentWhiteInactiveImage, transparentMaskImage }, Color.FromArgb(0, 0, 0, 0));
463530

464531
whiteShot.Dispose();
465532
blackShot.Dispose();
@@ -665,6 +732,8 @@ private static unsafe Bitmap[] CropEmptyEdges(Bitmap[] b1, Color trimColor)
665732
Bitmap[] final = new Bitmap[b1.Length];
666733
for(int i = 0; i < b1.Length; i++)
667734
{
735+
if (b1[i] == null)
736+
continue;
668737
final[i] = b1[i].Clone(new Rectangle(left, top, rightSize, bottomSize), b1[i].PixelFormat);
669738
b1[i].Dispose();
670739
}
@@ -733,6 +802,45 @@ private static unsafe Bitmap DifferentiateAlpha(Bitmap whiteBitmap, Bitmap black
733802
return empty ? null : final;
734803
}
735804

805+
private static unsafe Bitmap CreateMask(Bitmap bitmap)
806+
{
807+
if (bitmap == null)
808+
return null;
809+
int sizeX = bitmap.Width;
810+
int sizeY = bitmap.Height;
811+
var final = new Bitmap(sizeX, sizeY, PixelFormat.Format32bppArgb);
812+
var a = new UnsafeBitmap(bitmap);
813+
var f = new UnsafeBitmap(final);
814+
a.LockImage();
815+
f.LockImage();
816+
817+
for (int x = 0, y = 0; x < sizeX && y < sizeY;)
818+
{
819+
PixelData* pixelA = a.GetPixel(x, y);
820+
PixelData* pixelF = f.GetPixel(x, y);
821+
822+
if(pixelA->Alpha > 0)
823+
{
824+
pixelF->Blue = 0;
825+
pixelF->Green = 0;
826+
pixelF->Red = 0;
827+
pixelF->Alpha = 255;
828+
}
829+
830+
if (x == sizeX - 1)
831+
{
832+
y++;
833+
x = 0;
834+
continue;
835+
}
836+
x++;
837+
}
838+
839+
a.UnlockImage();
840+
f.UnlockImage();
841+
return final;
842+
}
843+
736844
private static byte ToByte(int i)
737845
{
738846
return (byte)(i > 255 ? 255 : (i < 0 ? 0 : i));

0 commit comments

Comments
 (0)