2015-09-25 18:39:08 +12:00
|
|
|
|
#region License Information (GPL v3)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
ShareX - A program that allows you to take screenshots and share any file type
|
2020-02-05 20:19:48 +13:00
|
|
|
|
Copyright (c) 2007-2020 ShareX Team
|
2015-09-25 18:39:08 +12:00
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
|
|
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#endregion License Information (GPL v3)
|
|
|
|
|
|
|
|
|
|
using ShareX.HelpersLib;
|
2015-10-01 12:48:33 +13:00
|
|
|
|
using ShareX.ScreenCaptureLib.Properties;
|
2015-09-25 18:39:08 +12:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
using System.Drawing.Imaging;
|
2015-09-25 22:02:31 +12:00
|
|
|
|
using System.Runtime.InteropServices;
|
2015-09-25 20:12:03 +12:00
|
|
|
|
using System.Threading;
|
2015-09-25 18:39:08 +12:00
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace ShareX.ScreenCaptureLib
|
|
|
|
|
{
|
2016-02-26 09:55:54 +13:00
|
|
|
|
public partial class ScrollingCaptureForm : Form
|
2015-09-25 18:39:08 +12:00
|
|
|
|
{
|
2020-03-24 08:33:26 +13:00
|
|
|
|
public event Action<Bitmap> ImageProcessRequested;
|
2015-09-26 00:33:13 +12:00
|
|
|
|
|
2016-08-23 07:39:38 +12:00
|
|
|
|
public ScrollingCaptureOptions Options { get; private set; }
|
|
|
|
|
public RegionCaptureOptions RegionCaptureOptions { get; private set; }
|
2020-03-24 08:33:26 +13:00
|
|
|
|
public Bitmap Result { get; private set; }
|
2015-09-25 20:12:03 +12:00
|
|
|
|
|
|
|
|
|
private WindowInfo selectedWindow;
|
2015-09-27 23:02:53 +13:00
|
|
|
|
private Rectangle selectedRectangle;
|
2020-03-21 14:41:34 +13:00
|
|
|
|
private List<Bitmap> images = new List<Bitmap>();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
private int currentScrollCount;
|
2015-09-27 22:11:06 +13:00
|
|
|
|
private bool isBusy, isCapturing, firstCapture, detectingScrollMethod;
|
|
|
|
|
private ScrollingCaptureScrollMethod currentScrollMethod;
|
2015-09-25 20:12:03 +12:00
|
|
|
|
|
2016-08-23 07:39:38 +12:00
|
|
|
|
public ScrollingCaptureForm(ScrollingCaptureOptions options, RegionCaptureOptions regionCaptureOptions, bool forceSelection = false)
|
2015-09-25 18:39:08 +12:00
|
|
|
|
{
|
2015-09-25 20:12:03 +12:00
|
|
|
|
Options = options;
|
2016-08-23 07:39:38 +12:00
|
|
|
|
RegionCaptureOptions = regionCaptureOptions;
|
2015-09-28 02:38:28 +13:00
|
|
|
|
|
2015-09-25 18:39:08 +12:00
|
|
|
|
InitializeComponent();
|
2019-06-25 06:36:16 +12:00
|
|
|
|
ShareXResources.ApplyTheme(this);
|
2015-09-28 02:38:28 +13:00
|
|
|
|
|
2016-07-14 04:23:34 +12:00
|
|
|
|
cbScrollMethod.Items.AddRange(Helpers.GetLocalizedEnumDescriptions<ScrollingCaptureScrollMethod>());
|
2015-09-26 17:57:26 +12:00
|
|
|
|
cbScrollMethod.SelectedIndex = (int)Options.ScrollMethod;
|
2016-07-14 04:23:34 +12:00
|
|
|
|
cbScrollTopMethodBeforeCapture.Items.AddRange(Helpers.GetLocalizedEnumDescriptions<ScrollingCaptureScrollTopMethod>());
|
2015-10-25 13:22:11 +13:00
|
|
|
|
cbScrollTopMethodBeforeCapture.SelectedIndex = (int)Options.ScrollTopMethodBeforeCapture;
|
2016-03-01 10:09:22 +13:00
|
|
|
|
nudStartDelay.SetValue(Options.StartDelay);
|
|
|
|
|
nudScrollDelay.SetValue(Options.ScrollDelay);
|
|
|
|
|
nudMaximumScrollCount.SetValue(Options.MaximumScrollCount);
|
2015-09-28 02:38:28 +13:00
|
|
|
|
cbStartSelectionAutomatically.Checked = Options.StartSelectionAutomatically;
|
2015-09-27 13:53:45 +13:00
|
|
|
|
cbStartCaptureAutomatically.Checked = Options.StartCaptureAutomatically;
|
2015-09-26 22:40:57 +12:00
|
|
|
|
cbAutoDetectScrollEnd.Checked = Options.AutoDetectScrollEnd;
|
|
|
|
|
cbRemoveDuplicates.Checked = Options.RemoveDuplicates;
|
2015-09-28 02:38:28 +13:00
|
|
|
|
cbAutoCombine.Checked = Options.AfterCaptureAutomaticallyCombine;
|
2015-10-03 14:17:00 +13:00
|
|
|
|
chkAutoUpload.Checked = Options.AutoUpload;
|
2015-09-26 22:40:57 +12:00
|
|
|
|
|
2015-09-27 20:55:42 +13:00
|
|
|
|
if (forceSelection || Options.StartSelectionAutomatically)
|
2015-09-26 22:40:57 +12:00
|
|
|
|
{
|
2015-09-27 13:53:45 +13:00
|
|
|
|
if (Options.StartCaptureAutomatically)
|
|
|
|
|
{
|
|
|
|
|
WindowState = FormWindowState.Minimized;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
SelectHandle();
|
|
|
|
|
}
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 22:02:31 +12:00
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if (disposing)
|
|
|
|
|
{
|
|
|
|
|
if (components != null)
|
|
|
|
|
{
|
|
|
|
|
components.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Clean();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 08:33:26 +13:00
|
|
|
|
protected void OnImageProcessRequested(Bitmap bmp)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2021-06-10 10:14:01 +12:00
|
|
|
|
ImageProcessRequested?.Invoke(bmp);
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 20:12:03 +12:00
|
|
|
|
private void btnSelectHandle_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-27 13:53:45 +13:00
|
|
|
|
SelectHandle();
|
2015-09-26 22:40:57 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 23:02:53 +13:00
|
|
|
|
private void btnSelectRectangle_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SelectRectangle();
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 13:53:45 +13:00
|
|
|
|
private void SelectHandle()
|
2015-09-26 22:40:57 +12:00
|
|
|
|
{
|
2015-09-27 13:53:45 +13:00
|
|
|
|
WindowState = FormWindowState.Minimized;
|
2015-09-25 20:12:03 +12:00
|
|
|
|
|
2015-09-27 20:03:10 +13:00
|
|
|
|
bool capturing = false;
|
|
|
|
|
|
2015-09-25 20:12:03 +12:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(250);
|
2015-09-27 23:02:53 +13:00
|
|
|
|
|
2016-09-05 22:31:49 +12:00
|
|
|
|
SimpleWindowInfo simpleWindowInfo = RegionCaptureTasks.GetWindowInfo(RegionCaptureOptions);
|
2015-09-25 20:12:03 +12:00
|
|
|
|
|
2015-09-27 13:53:45 +13:00
|
|
|
|
if (simpleWindowInfo != null)
|
|
|
|
|
{
|
|
|
|
|
selectedWindow = new WindowInfo(simpleWindowInfo.Handle);
|
2016-05-25 06:15:45 +12:00
|
|
|
|
lblControlText.Text = selectedWindow.ClassName ?? "";
|
2015-09-27 23:02:53 +13:00
|
|
|
|
selectedRectangle = simpleWindowInfo.Rectangle;
|
|
|
|
|
lblSelectedRectangle.Text = selectedRectangle.ToString();
|
|
|
|
|
btnSelectRectangle.Enabled = btnCapture.Enabled = true;
|
2015-09-27 13:53:45 +13:00
|
|
|
|
|
|
|
|
|
if (Options.StartCaptureAutomatically)
|
|
|
|
|
{
|
2015-09-27 20:03:10 +13:00
|
|
|
|
capturing = true;
|
2015-09-27 13:53:45 +13:00
|
|
|
|
StartCapture();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
btnCapture.Enabled = false;
|
|
|
|
|
}
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
2015-09-27 13:53:45 +13:00
|
|
|
|
finally
|
2015-09-25 20:12:03 +12:00
|
|
|
|
{
|
2016-03-10 05:37:54 +13:00
|
|
|
|
if (!capturing) this.ForceActivate();
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 23:02:53 +13:00
|
|
|
|
private void SelectRectangle()
|
|
|
|
|
{
|
|
|
|
|
WindowState = FormWindowState.Minimized;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(250);
|
|
|
|
|
|
2021-06-10 10:14:01 +12:00
|
|
|
|
if (RegionCaptureTasks.GetRectangleRegion(out Rectangle rect, RegionCaptureOptions))
|
2015-09-27 23:02:53 +13:00
|
|
|
|
{
|
|
|
|
|
selectedRectangle = rect;
|
|
|
|
|
lblSelectedRectangle.Text = selectedRectangle.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
2016-03-10 05:37:54 +13:00
|
|
|
|
this.ForceActivate();
|
2015-09-27 23:02:53 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 20:12:03 +12:00
|
|
|
|
private void btnCapture_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-27 20:49:43 +13:00
|
|
|
|
if (isCapturing)
|
|
|
|
|
{
|
|
|
|
|
StopCapture();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StartCapture();
|
|
|
|
|
}
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartCapture()
|
|
|
|
|
{
|
2015-09-27 20:49:43 +13:00
|
|
|
|
isCapturing = true;
|
2015-10-01 12:48:33 +13:00
|
|
|
|
btnCapture.Text = Resources.ScrollingCaptureForm_StartCapture_Stop_capture;
|
2015-09-27 13:53:45 +13:00
|
|
|
|
WindowState = FormWindowState.Minimized;
|
|
|
|
|
firstCapture = true;
|
2015-09-27 22:11:06 +13:00
|
|
|
|
|
|
|
|
|
if (Options.ScrollMethod == ScrollingCaptureScrollMethod.Automatic)
|
|
|
|
|
{
|
|
|
|
|
currentScrollMethod = ScrollingCaptureScrollMethod.SendMessageScroll;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
currentScrollMethod = Options.ScrollMethod;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detectingScrollMethod = true;
|
2015-09-25 22:02:31 +12:00
|
|
|
|
Clean();
|
2015-09-25 20:12:03 +12:00
|
|
|
|
selectedWindow.Activate();
|
2015-09-27 20:49:43 +13:00
|
|
|
|
captureTimer.Interval = Options.StartDelay;
|
2015-09-25 20:12:03 +12:00
|
|
|
|
captureTimer.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StopCapture()
|
|
|
|
|
{
|
|
|
|
|
captureTimer.Stop();
|
2015-10-01 12:48:33 +13:00
|
|
|
|
btnCapture.Text = Resources.ScrollingCaptureForm_StopCapture_Start_capture;
|
2016-03-10 05:37:54 +13:00
|
|
|
|
if (!Options.AutoUpload) this.ForceActivate();
|
2015-09-25 22:02:31 +12:00
|
|
|
|
tcScrollingCapture.SelectedTab = tpOutput;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
StartingProcess();
|
2015-09-26 22:40:57 +12:00
|
|
|
|
if (Options.RemoveDuplicates) RemoveDuplicates();
|
2015-09-30 02:37:18 +13:00
|
|
|
|
txtImagesCount.Text = images.Count.ToString();
|
2015-09-28 01:46:29 +13:00
|
|
|
|
btnGuessEdges.Enabled = btnGuessCombineAdjustments.Enabled = images.Count > 1;
|
|
|
|
|
btnStartTask.Enabled = btnResetCombine.Enabled = images.Count > 0;
|
2015-09-30 02:37:18 +13:00
|
|
|
|
nudIgnoreLast.Maximum = images.Count > 1 ? images.Count - 1 : 0;
|
2015-09-28 02:38:28 +13:00
|
|
|
|
ResetOffsets();
|
|
|
|
|
if (Options.AfterCaptureAutomaticallyCombine)
|
|
|
|
|
{
|
|
|
|
|
GuessEdges();
|
|
|
|
|
GuessCombineAdjustments();
|
|
|
|
|
}
|
|
|
|
|
CombineAndPreviewImages();
|
2015-10-03 14:17:00 +13:00
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
EndingProcess();
|
2015-09-27 20:49:43 +13:00
|
|
|
|
isCapturing = false;
|
2015-10-03 14:17:00 +13:00
|
|
|
|
|
2015-10-03 14:29:47 +13:00
|
|
|
|
if (Options.AutoUpload) StartProcess();
|
2015-09-25 22:02:31 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Clean()
|
|
|
|
|
{
|
|
|
|
|
currentScrollCount = 0;
|
|
|
|
|
|
2016-01-19 02:43:40 +13:00
|
|
|
|
CleanPictureBox();
|
|
|
|
|
|
2015-09-25 22:02:31 +12:00
|
|
|
|
if (images != null)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
foreach (Bitmap bmp in images)
|
2015-09-25 22:02:31 +12:00
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
if (bmp != null)
|
2015-09-25 22:02:31 +12:00
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
bmp.Dispose();
|
2015-09-25 22:02:31 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
images.Clear();
|
|
|
|
|
}
|
2015-09-30 04:36:57 +13:00
|
|
|
|
|
|
|
|
|
if (Result != null)
|
|
|
|
|
{
|
|
|
|
|
Result.Dispose();
|
|
|
|
|
}
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-30 01:57:26 +13:00
|
|
|
|
private void CleanPictureBox(Image img = null)
|
2015-09-27 18:57:02 +13:00
|
|
|
|
{
|
|
|
|
|
Image temp = pbOutput.Image;
|
|
|
|
|
|
2015-09-30 01:57:26 +13:00
|
|
|
|
pbOutput.Image = img;
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
if (temp != null)
|
|
|
|
|
{
|
|
|
|
|
temp.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
private void RemoveDuplicates()
|
2015-09-26 21:18:38 +12:00
|
|
|
|
{
|
|
|
|
|
if (images.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
for (int i = images.Count - 1; i > 0; i--)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
bool result = ImageHelpers.IsImagesEqual(images[i], images[i - 1]);
|
2015-09-26 21:18:38 +12:00
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
Bitmap bmp = images[i];
|
|
|
|
|
images.Remove(bmp);
|
|
|
|
|
bmp.Dispose();
|
2015-09-26 21:18:38 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 20:12:03 +12:00
|
|
|
|
private void captureTimer_Tick(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-27 19:21:36 +13:00
|
|
|
|
if (firstCapture)
|
2015-09-27 13:53:45 +13:00
|
|
|
|
{
|
|
|
|
|
firstCapture = false;
|
2015-09-27 19:21:36 +13:00
|
|
|
|
captureTimer.Interval = Options.ScrollDelay;
|
|
|
|
|
|
2015-10-25 13:22:11 +13:00
|
|
|
|
if (Options.ScrollTopMethodBeforeCapture == ScrollingCaptureScrollTopMethod.All || Options.ScrollTopMethodBeforeCapture == ScrollingCaptureScrollTopMethod.KeyPressHome)
|
2015-09-27 19:21:36 +13:00
|
|
|
|
{
|
|
|
|
|
InputHelpers.SendKeyPress(VirtualKeyCode.HOME);
|
2015-10-25 13:22:11 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Options.ScrollTopMethodBeforeCapture == ScrollingCaptureScrollTopMethod.All || Options.ScrollTopMethodBeforeCapture == ScrollingCaptureScrollTopMethod.SendMessageTop)
|
|
|
|
|
{
|
2015-09-27 20:03:10 +13:00
|
|
|
|
NativeMethods.SendMessage(selectedWindow.Handle, (int)WindowsMessages.VSCROLL, (int)ScrollBarCommands.SB_TOP, 0);
|
2015-10-25 13:22:11 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Options.ScrollTopMethodBeforeCapture != ScrollingCaptureScrollTopMethod.None)
|
|
|
|
|
{
|
2015-09-27 19:21:36 +13:00
|
|
|
|
return;
|
|
|
|
|
}
|
2015-09-27 13:53:45 +13:00
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 02:23:45 +12:00
|
|
|
|
Screenshot screenshot = new Screenshot() { CaptureCursor = false };
|
2020-03-21 14:41:34 +13:00
|
|
|
|
Bitmap bmp = screenshot.CaptureRectangle(selectedRectangle);
|
2015-09-25 22:02:31 +12:00
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
if (bmp != null)
|
2015-09-25 22:02:31 +12:00
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
images.Add(bmp);
|
2015-09-25 22:02:31 +12:00
|
|
|
|
}
|
2015-09-25 20:12:03 +12:00
|
|
|
|
|
2015-09-27 22:11:06 +13:00
|
|
|
|
if (Options.ScrollMethod == ScrollingCaptureScrollMethod.Automatic && detectingScrollMethod && images.Count > 1 && IsLastTwoImagesSame())
|
|
|
|
|
{
|
|
|
|
|
if (currentScrollMethod == ScrollingCaptureScrollMethod.SendMessageScroll)
|
|
|
|
|
{
|
|
|
|
|
currentScrollMethod = ScrollingCaptureScrollMethod.KeyPressPageDown;
|
|
|
|
|
}
|
|
|
|
|
else if (currentScrollMethod == ScrollingCaptureScrollMethod.KeyPressPageDown)
|
|
|
|
|
{
|
|
|
|
|
currentScrollMethod = ScrollingCaptureScrollMethod.MouseWheel;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StopCapture();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (currentScrollCount == Options.MaximumScrollCount || (Options.AutoDetectScrollEnd && IsScrollReachedBottom(selectedWindow.Handle)))
|
2015-09-25 20:12:03 +12:00
|
|
|
|
{
|
|
|
|
|
StopCapture();
|
|
|
|
|
}
|
2015-09-27 22:11:06 +13:00
|
|
|
|
else if (images.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
detectingScrollMethod = false;
|
|
|
|
|
}
|
2015-09-25 22:02:31 +12:00
|
|
|
|
|
2015-09-27 22:11:06 +13:00
|
|
|
|
switch (currentScrollMethod)
|
2015-09-26 17:57:26 +12:00
|
|
|
|
{
|
2015-09-27 13:53:45 +13:00
|
|
|
|
case ScrollingCaptureScrollMethod.Automatic:
|
2015-09-26 17:57:26 +12:00
|
|
|
|
case ScrollingCaptureScrollMethod.SendMessageScroll:
|
|
|
|
|
NativeMethods.SendMessage(selectedWindow.Handle, (int)WindowsMessages.VSCROLL, (int)ScrollBarCommands.SB_PAGEDOWN, 0);
|
|
|
|
|
break;
|
|
|
|
|
case ScrollingCaptureScrollMethod.KeyPressPageDown:
|
|
|
|
|
InputHelpers.SendKeyPress(VirtualKeyCode.NEXT);
|
|
|
|
|
break;
|
|
|
|
|
case ScrollingCaptureScrollMethod.MouseWheel:
|
2015-09-26 22:40:57 +12:00
|
|
|
|
InputHelpers.SendMouseWheel(-120);
|
2015-09-26 17:57:26 +12:00
|
|
|
|
break;
|
|
|
|
|
}
|
2015-09-27 22:11:06 +13:00
|
|
|
|
|
|
|
|
|
currentScrollCount++;
|
2015-09-25 20:12:03 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
private void cbScrollMethod_SelectedIndexChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.ScrollMethod = (ScrollingCaptureScrollMethod)cbScrollMethod.SelectedIndex;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-25 13:22:11 +13:00
|
|
|
|
private void cbScrollTopMethodBeforeCapture_SelectedIndexChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.ScrollTopMethodBeforeCapture = (ScrollingCaptureScrollTopMethod)cbScrollTopMethodBeforeCapture.SelectedIndex;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 20:49:43 +13:00
|
|
|
|
private void nudStartDelay_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.StartDelay = (int)nudStartDelay.Value;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 20:12:03 +12:00
|
|
|
|
private void nudScrollDelay_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.ScrollDelay = (int)nudScrollDelay.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudMaximumScrollCount_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.MaximumScrollCount = (int)nudMaximumScrollCount.Value;
|
2015-09-25 18:39:08 +12:00
|
|
|
|
}
|
2015-09-25 22:32:53 +12:00
|
|
|
|
|
2015-09-28 02:38:28 +13:00
|
|
|
|
private void cbStartSelectionAutomatically_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.StartSelectionAutomatically = cbStartSelectionAutomatically.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 13:53:45 +13:00
|
|
|
|
private void cbStartCaptureAutomatically_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.StartCaptureAutomatically = cbStartCaptureAutomatically.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 21:18:38 +12:00
|
|
|
|
private void cbAutoDetectScrollEnd_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.AutoDetectScrollEnd = cbAutoDetectScrollEnd.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
private void cbRemoveDuplicates_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.RemoveDuplicates = cbRemoveDuplicates.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-28 02:38:28 +13:00
|
|
|
|
private void cbAutoCombine_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.AfterCaptureAutomaticallyCombine = cbAutoCombine.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 22:32:53 +12:00
|
|
|
|
private bool IsScrollReachedBottom(IntPtr handle)
|
|
|
|
|
{
|
|
|
|
|
SCROLLINFO scrollInfo = new SCROLLINFO();
|
|
|
|
|
scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo);
|
|
|
|
|
scrollInfo.fMask = (uint)(ScrollInfoMask.SIF_RANGE | ScrollInfoMask.SIF_PAGE | ScrollInfoMask.SIF_TRACKPOS);
|
|
|
|
|
|
|
|
|
|
if (NativeMethods.GetScrollInfo(handle, (int)SBOrientation.SB_VERT, ref scrollInfo))
|
|
|
|
|
{
|
|
|
|
|
return scrollInfo.nMax == scrollInfo.nTrackPos + scrollInfo.nPage - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 22:11:06 +13:00
|
|
|
|
return IsLastTwoImagesSame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsLastTwoImagesSame()
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
|
2015-09-25 22:32:53 +12:00
|
|
|
|
if (images.Count > 1)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
result = ImageHelpers.IsImagesEqual(images[images.Count - 1], images[images.Count - 2]);
|
2015-09-25 22:32:53 +12:00
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
Bitmap last = images[images.Count - 1];
|
2015-09-25 22:32:53 +12:00
|
|
|
|
images.Remove(last);
|
|
|
|
|
last.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 22:11:06 +13:00
|
|
|
|
return result;
|
2015-09-25 22:32:53 +12:00
|
|
|
|
}
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
|
|
|
|
private void nudTrimLeft_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.TrimLeftEdge = (int)nudTrimLeft.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudTrimTop_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.TrimTopEdge = (int)nudTrimTop.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudTrimRight_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.TrimRightEdge = (int)nudTrimRight.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudTrimBottom_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.TrimBottomEdge = (int)nudTrimBottom.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudCombineVertical_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.CombineAdjustmentVertical = (int)nudCombineVertical.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void nudCombineLastVertical_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.CombineAdjustmentLastVertical = (int)nudCombineLastVertical.Value;
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImagesFromControl();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-30 02:37:18 +13:00
|
|
|
|
private void nudIgnoreLast_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.IgnoreLast = (int)nudIgnoreLast.Value;
|
|
|
|
|
txtImagesCount.Text = (images.Count - Options.IgnoreLast).ToString();
|
|
|
|
|
CombineAndPreviewImagesFromControl();
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
private void btnGuessEdges_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-27 18:57:02 +13:00
|
|
|
|
StartingProcess();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
GuessEdges();
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImages();
|
|
|
|
|
EndingProcess();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void btnGuessCombineAdjustments_Click(object sender, EventArgs e)
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2015-09-27 18:57:02 +13:00
|
|
|
|
StartingProcess();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
GuessCombineAdjustments();
|
2015-09-27 18:57:02 +13:00
|
|
|
|
CombineAndPreviewImages();
|
|
|
|
|
EndingProcess();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
private void btnProcess_Click(object sender, EventArgs e)
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2015-10-03 14:17:00 +13:00
|
|
|
|
StartProcess();
|
2015-09-25 23:36:13 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
private void StartingProcess()
|
2015-09-25 23:36:13 +12:00
|
|
|
|
{
|
2015-09-27 18:57:02 +13:00
|
|
|
|
isBusy = true;
|
|
|
|
|
CleanPictureBox();
|
|
|
|
|
lblProcessing.Visible = true;
|
|
|
|
|
Application.DoEvents();
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-03 14:17:00 +13:00
|
|
|
|
private void StartProcess()
|
|
|
|
|
{
|
|
|
|
|
if (Result != null)
|
|
|
|
|
{
|
2020-03-24 08:33:26 +13:00
|
|
|
|
OnImageProcessRequested((Bitmap)Result.Clone());
|
2015-10-03 14:17:00 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
private void EndingProcess()
|
|
|
|
|
{
|
|
|
|
|
lblProcessing.Visible = false;
|
|
|
|
|
isBusy = false;
|
2015-09-25 23:36:13 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
private void btnResetCombine_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-27 18:57:02 +13:00
|
|
|
|
StartingProcess();
|
2015-09-28 02:38:28 +13:00
|
|
|
|
ResetOffsets();
|
|
|
|
|
CombineAndPreviewImages();
|
2015-09-27 18:57:02 +13:00
|
|
|
|
EndingProcess();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-28 02:38:28 +13:00
|
|
|
|
private void ResetOffsets()
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2015-09-30 02:37:18 +13:00
|
|
|
|
nudTrimLeft.Value = nudTrimTop.Value = nudTrimRight.Value = nudTrimBottom.Value = nudCombineVertical.Value = nudCombineLastVertical.Value = nudIgnoreLast.Value = 0;
|
|
|
|
|
Options.TrimLeftEdge = Options.TrimTopEdge = Options.TrimRightEdge = Options.TrimBottomEdge =
|
|
|
|
|
Options.CombineAdjustmentVertical = Options.CombineAdjustmentLastVertical = Options.IgnoreLast = 0;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
private void CombineAndPreviewImagesFromControl()
|
2015-09-25 23:36:13 +12:00
|
|
|
|
{
|
2015-09-26 12:42:43 +12:00
|
|
|
|
if (!isBusy)
|
|
|
|
|
{
|
2015-09-30 01:57:26 +13:00
|
|
|
|
Result = CombineImages();
|
|
|
|
|
CleanPictureBox(Result);
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 18:57:02 +13:00
|
|
|
|
private void CombineAndPreviewImages()
|
|
|
|
|
{
|
|
|
|
|
Result = CombineImages();
|
|
|
|
|
pbOutput.Image = Result;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 08:33:26 +13:00
|
|
|
|
private Bitmap CombineImages()
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
|
|
|
|
if (images == null || images.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (images.Count == 1)
|
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
return (Bitmap)images[0].Clone();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
List<Bitmap> output = new List<Bitmap>();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
2015-09-30 02:37:18 +13:00
|
|
|
|
for (int i = 0; i < images.Count - Options.IgnoreLast; i++)
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
Bitmap newImage;
|
|
|
|
|
Bitmap image = images[i];
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
2016-10-19 02:30:08 +13:00
|
|
|
|
if (Options.TrimLeftEdge > 0 || Options.TrimTopEdge > 0 || Options.TrimRightEdge > 0 || Options.TrimBottomEdge > 0 ||
|
2015-09-26 12:42:43 +12:00
|
|
|
|
Options.CombineAdjustmentVertical > 0 || Options.CombineAdjustmentLastVertical > 0)
|
|
|
|
|
{
|
|
|
|
|
Rectangle rect = new Rectangle(Options.TrimLeftEdge, Options.TrimTopEdge, image.Width - Options.TrimLeftEdge - Options.TrimRightEdge,
|
|
|
|
|
image.Height - Options.TrimTopEdge - Options.TrimBottomEdge);
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
2015-09-26 20:47:48 +12:00
|
|
|
|
if (i == images.Count - 1)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
rect.Y += Options.CombineAdjustmentLastVertical;
|
|
|
|
|
rect.Height -= Options.CombineAdjustmentLastVertical;
|
|
|
|
|
}
|
|
|
|
|
else if (i > 0)
|
|
|
|
|
{
|
|
|
|
|
rect.Y += Options.CombineAdjustmentVertical;
|
|
|
|
|
rect.Height -= Options.CombineAdjustmentVertical;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
newImage = ImageHelpers.CropBitmap(image, rect);
|
2015-09-30 01:57:26 +13:00
|
|
|
|
|
|
|
|
|
if (newImage == null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
2015-09-30 04:36:57 +13:00
|
|
|
|
else
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2020-03-21 14:41:34 +13:00
|
|
|
|
newImage = (Bitmap)image.Clone();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
2015-09-26 12:42:43 +12:00
|
|
|
|
|
|
|
|
|
output.Add(newImage);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 08:33:26 +13:00
|
|
|
|
Bitmap bmpResult = ImageHelpers.CombineImages(output);
|
2015-09-26 12:42:43 +12:00
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
foreach (Bitmap image in output)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
if (image != null)
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2015-09-26 12:42:43 +12:00
|
|
|
|
image.Dispose();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
output.Clear();
|
2015-09-25 23:14:51 +12:00
|
|
|
|
|
2020-03-24 08:33:26 +13:00
|
|
|
|
return bmpResult;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GuessEdges()
|
|
|
|
|
{
|
|
|
|
|
if (images.Count < 2) return;
|
|
|
|
|
|
|
|
|
|
nudTrimLeft.Value = nudTrimTop.Value = nudTrimRight.Value = nudTrimBottom.Value = 0;
|
|
|
|
|
|
2015-09-26 20:47:48 +12:00
|
|
|
|
Padding result = new Padding();
|
2015-09-26 12:42:43 +12:00
|
|
|
|
|
2015-09-26 20:47:48 +12:00
|
|
|
|
for (int i = 0; i < images.Count - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
Padding edges = GuessEdges(images[i], images[i + 1]);
|
|
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
result = edges;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result.Left = Math.Min(result.Left, edges.Left);
|
|
|
|
|
result.Top = Math.Min(result.Top, edges.Top);
|
|
|
|
|
result.Right = Math.Min(result.Right, edges.Right);
|
|
|
|
|
result.Bottom = Math.Min(result.Bottom, edges.Bottom);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-01 10:09:22 +13:00
|
|
|
|
nudTrimLeft.SetValue(result.Left);
|
|
|
|
|
nudTrimTop.SetValue(result.Top);
|
|
|
|
|
nudTrimRight.SetValue(result.Right);
|
|
|
|
|
nudTrimBottom.SetValue(result.Bottom);
|
2015-09-26 20:47:48 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-03 14:17:00 +13:00
|
|
|
|
private void chkAutoUpload_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Options.AutoUpload = chkAutoUpload.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
private Padding GuessEdges(Bitmap img1, Bitmap img2)
|
2015-09-26 20:47:48 +12:00
|
|
|
|
{
|
|
|
|
|
Padding result = new Padding();
|
|
|
|
|
Rectangle rect = new Rectangle(0, 0, img1.Width, img1.Height);
|
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
using (UnsafeBitmap bmp1 = new UnsafeBitmap(img1, true, ImageLockMode.ReadOnly))
|
|
|
|
|
using (UnsafeBitmap bmp2 = new UnsafeBitmap(img2, true, ImageLockMode.ReadOnly))
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
bool valueFound = false;
|
|
|
|
|
|
|
|
|
|
// Left edge
|
|
|
|
|
for (int x = rect.X; !valueFound && x < rect.Width; x++)
|
2015-09-25 23:14:51 +12:00
|
|
|
|
{
|
2015-09-26 12:42:43 +12:00
|
|
|
|
for (int y = rect.Y; y < rect.Height; y++)
|
|
|
|
|
{
|
|
|
|
|
if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
valueFound = true;
|
2015-09-26 20:47:48 +12:00
|
|
|
|
result.Left = x;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
rect.X = x;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
valueFound = false;
|
|
|
|
|
|
|
|
|
|
// Top edge
|
|
|
|
|
for (int y = rect.Y; !valueFound && y < rect.Height; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = rect.X; x < rect.Width; x++)
|
|
|
|
|
{
|
|
|
|
|
if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
valueFound = true;
|
2015-09-26 20:47:48 +12:00
|
|
|
|
result.Top = y;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
rect.Y = y;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
valueFound = false;
|
|
|
|
|
|
|
|
|
|
// Right edge
|
|
|
|
|
for (int x = rect.Width - 1; !valueFound && x >= rect.X; x--)
|
|
|
|
|
{
|
|
|
|
|
for (int y = rect.Y; y < rect.Height; y++)
|
|
|
|
|
{
|
|
|
|
|
if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
valueFound = true;
|
2015-09-26 20:47:48 +12:00
|
|
|
|
result.Right = rect.Width - x - 1;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
rect.Width = x + 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
valueFound = false;
|
|
|
|
|
|
|
|
|
|
// Bottom edge
|
|
|
|
|
for (int y = rect.Height - 1; !valueFound && y >= rect.X; y--)
|
|
|
|
|
{
|
|
|
|
|
for (int x = rect.X; x < rect.Width; x++)
|
|
|
|
|
{
|
|
|
|
|
if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
valueFound = true;
|
2015-09-26 20:47:48 +12:00
|
|
|
|
result.Bottom = rect.Height - y - 1;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
rect.Height = y + 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 20:47:48 +12:00
|
|
|
|
return result;
|
2015-09-25 23:14:51 +12:00
|
|
|
|
}
|
2015-09-26 00:33:13 +12:00
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
private void GuessCombineAdjustments()
|
2015-09-26 00:33:13 +12:00
|
|
|
|
{
|
2015-09-26 12:42:43 +12:00
|
|
|
|
if (images.Count > 1)
|
2015-09-26 00:33:13 +12:00
|
|
|
|
{
|
2015-09-26 19:16:33 +12:00
|
|
|
|
int vertical = 0;
|
|
|
|
|
|
2015-09-26 20:47:48 +12:00
|
|
|
|
for (int i = 0; i < images.Count - 2; i++)
|
2015-09-26 19:16:33 +12:00
|
|
|
|
{
|
2015-09-26 20:47:48 +12:00
|
|
|
|
int temp = CalculateVerticalOffset(images[i], images[i + 1]);
|
2015-09-30 04:36:57 +13:00
|
|
|
|
vertical = Math.Max(vertical, temp);
|
2015-09-26 19:16:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-01 10:09:22 +13:00
|
|
|
|
nudCombineVertical.SetValue(vertical);
|
|
|
|
|
nudCombineLastVertical.SetValue(CalculateVerticalOffset(images[images.Count - 2], images[images.Count - 1]));
|
2015-09-26 00:33:13 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-26 12:42:43 +12:00
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
private int CalculateVerticalOffset(Bitmap img1, Bitmap img2, int ignoreRightOffset = 50)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2015-09-26 22:40:57 +12:00
|
|
|
|
int lastMatchCount = 0;
|
|
|
|
|
int lastMatchOffset = 0;
|
|
|
|
|
|
2015-09-26 12:42:43 +12:00
|
|
|
|
Rectangle rect = new Rectangle(Options.TrimLeftEdge, Options.TrimTopEdge,
|
|
|
|
|
img1.Width - Options.TrimLeftEdge - Options.TrimRightEdge - (img1.Width > ignoreRightOffset ? ignoreRightOffset : 0),
|
|
|
|
|
img1.Height - Options.TrimTopEdge - Options.TrimBottomEdge);
|
|
|
|
|
|
2020-03-21 14:41:34 +13:00
|
|
|
|
using (UnsafeBitmap bmp1 = new UnsafeBitmap(img1, true, ImageLockMode.ReadOnly))
|
|
|
|
|
using (UnsafeBitmap bmp2 = new UnsafeBitmap(img2, true, ImageLockMode.ReadOnly))
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2015-09-26 19:16:33 +12:00
|
|
|
|
for (int y = rect.Y; y < rect.Bottom; y++)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
bool isLineMatches = true;
|
|
|
|
|
|
2015-09-26 19:16:33 +12:00
|
|
|
|
for (int x = rect.X; x < rect.Right; x++)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2015-09-26 19:16:33 +12:00
|
|
|
|
if (bmp2.GetPixel(x, y) != bmp1.GetPixel(x, rect.Bottom - 1))
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
isLineMatches = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isLineMatches)
|
|
|
|
|
{
|
2015-09-26 22:40:57 +12:00
|
|
|
|
int lineMatchesCount = 1;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
int y3 = 2;
|
|
|
|
|
|
|
|
|
|
for (int y2 = y - 1; y2 >= rect.Y; y2--)
|
|
|
|
|
{
|
|
|
|
|
bool isLineMatches2 = true;
|
|
|
|
|
|
2015-09-26 19:16:33 +12:00
|
|
|
|
for (int x2 = rect.X; x2 < rect.Right; x2++)
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
2015-09-26 19:16:33 +12:00
|
|
|
|
if (bmp2.GetPixel(x2, y2) != bmp1.GetPixel(x2, rect.Bottom - y3))
|
2015-09-26 12:42:43 +12:00
|
|
|
|
{
|
|
|
|
|
isLineMatches2 = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isLineMatches2)
|
|
|
|
|
{
|
|
|
|
|
lineMatchesCount++;
|
|
|
|
|
y3++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-09-26 22:40:57 +12:00
|
|
|
|
}
|
2015-09-26 12:42:43 +12:00
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
if (lineMatchesCount > lastMatchCount)
|
|
|
|
|
{
|
|
|
|
|
lastMatchCount = lineMatchesCount;
|
|
|
|
|
lastMatchOffset = y - rect.Y + 1;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-26 22:40:57 +12:00
|
|
|
|
return lastMatchOffset;
|
2015-09-26 12:42:43 +12:00
|
|
|
|
}
|
2015-09-25 18:39:08 +12:00
|
|
|
|
}
|
|
|
|
|
}
|