868 lines
30 KiB
C#
868 lines
30 KiB
C#
//#define InitialPath
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
using System.IO;
|
||
using System.Diagnostics;
|
||
|
||
namespace ImageCompressor
|
||
{
|
||
public partial class ImageCompressorForm : Form
|
||
{
|
||
public ImageCompressorForm()
|
||
{
|
||
manager = new FilesManager(this);
|
||
}
|
||
/// <summary>
|
||
/// 后台读取图片,并且负责运行
|
||
/// </summary>
|
||
FilesManager manager;
|
||
/// <summary>
|
||
/// 替换原有的Panel作为进度条
|
||
/// </summary>
|
||
NewProgressPanel newProgressPanel;
|
||
protected override void OnLoad(EventArgs e)
|
||
{
|
||
this.newProgressPanel = new NewProgressPanel(new Font("Bahnschrift Condensed", 12F), SystemColors.ControlDark);
|
||
|
||
InitializeComponent();
|
||
SetLanguage();
|
||
|
||
newProgressPanel.Clone(ProgressPanel);
|
||
|
||
ProgressPanel.Visible = false;
|
||
this.Controls.Add(this.newProgressPanel);
|
||
|
||
OnSizeChanged(null);
|
||
|
||
ZoomInPictureBox.Visible = false;
|
||
|
||
PostPictureBox.MouseMove += OnPictureMouseMovePost;
|
||
PreviousPictureBox.MouseMove += OnPictureMouseMovePrevious;
|
||
ZoomInPictureBox.MouseMove += OnZoomMouseMove;
|
||
PostPictureBox.MouseWheel += OnZoomMouseWheelPost;
|
||
PreviousPictureBox.MouseWheel += OnZoomMouseWheelPre;
|
||
|
||
MaxWidthPixelTextBox.Leave += MaxWidthPixelTextBox_FocusLeave;
|
||
MaxHeightPixelTextBox.Leave += MaxHeightPixelTextBox_FocusLeave;
|
||
SkipFileSizeTextBox.Leave += SkipFileSizeTextBox_FocusLeave;
|
||
MaxWidthPixelTextBox.KeyDown += TextBox_KeyDown;
|
||
MaxHeightPixelTextBox.KeyDown += TextBox_KeyDown;
|
||
SkipFileSizeTextBox.KeyDown += TextBox_KeyDown;
|
||
|
||
ApplySettingsFromForm();
|
||
UpdateDisplayInfo();
|
||
UpdateRunButtonText();
|
||
SetProgressValue(0);
|
||
|
||
PathTextBox.DragDrop += Box_DragDrop;
|
||
PathTextBox.DragEnter += Box_DragEnter;
|
||
|
||
this.DragDrop += Box_DragDrop;
|
||
this.DragEnter += Box_DragEnter;
|
||
|
||
|
||
|
||
#if InitialPath && DEBUG
|
||
|
||
//string path = @"C:\Users\wucl12\Downloads\Test\Italy";
|
||
string path = @"D:\Users\MandO\Downloads\重庆照片";
|
||
dragDropFolderPaths.Add(path);
|
||
UpdateDropFilePaths();
|
||
UpdateRunButtonText();
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// 启动时设置语言
|
||
/// </summary>
|
||
void SetLanguage()
|
||
{
|
||
if(!Localize.IsEN)
|
||
{
|
||
|
||
this.PathTextBox.Font = new System.Drawing.Font("等线", 12F);
|
||
this.SizeEstimateLabel.Font = new Font("等线", 12F);
|
||
this.KeepOriginalCheckBox.Font = new Font("等线", 12F);
|
||
this.MaxPixelMultiplyLabel.Font = new Font("等线", 12F);
|
||
this.MaxPixelLimitLabel.Font = new Font("等线", 12F);
|
||
//this.CompressLevelTextLabel.Font = new Font("等线", 15F);
|
||
this.TitleTextLabel.Font = new Font("等线", 12F);
|
||
this.InfoLabel.Font = new Font("等线", 12F);
|
||
this.RunButton.Font = new Font("等线", 12F, FontStyle.Bold);
|
||
this.SubFolderCheckBox.Font = new Font("等线", 12F);
|
||
this.SkipFileSizeLabel.Font = new Font("等线", 12F);
|
||
this.CompressLevelLabel.Font = new Font("等线", 12F);
|
||
}
|
||
|
||
this.CompressLevelLabel.Text = Localize.Get("Compress Level (1-10)");
|
||
this.SkipFileSizeLabel.Text = Localize.Get("Skip File Size (KB)");
|
||
|
||
this.KeepOriginalCheckBox.Text = Localize.Get("Keep Original (Compress in new folder)");
|
||
this.SubFolderCheckBox.Text = Localize.Get("Include SubFolders");
|
||
|
||
this.MaxPixelLimitLabel.Text = Localize.Get("Max Pixel Limit");
|
||
this.TitleTextLabel.Text = Localize.Get("Image Compressor") +" 2026.02.02 by WR";
|
||
|
||
this.Text = Localize.Get("Image Compressor");
|
||
}
|
||
|
||
|
||
#region Resize
|
||
/// <summary>
|
||
/// 点击到左右边界
|
||
/// </summary>
|
||
ClickResize clickResizeHorizen = ClickResize.None;
|
||
/// <summary>
|
||
/// 点击到上下边界
|
||
/// </summary>
|
||
ClickResize clickResizeVertical = ClickResize.None;
|
||
/// <summary>
|
||
/// 记录点击边界值
|
||
/// </summary>
|
||
enum ClickResize
|
||
{
|
||
None,
|
||
Left,
|
||
Right,
|
||
Top,
|
||
Buttom,
|
||
}
|
||
/// <summary>
|
||
/// 鼠标点击位置是移动还是缩放
|
||
/// </summary>
|
||
enum SizeChangeState
|
||
{
|
||
None,
|
||
ChangeSize,
|
||
Move,
|
||
}
|
||
/// <summary>
|
||
/// 记录移动或者缩放状态
|
||
/// </summary>
|
||
SizeChangeState sizeChangeState = SizeChangeState.None;
|
||
|
||
/// <summary>
|
||
/// 绘制尺寸时的间距控制常数
|
||
/// </summary>
|
||
const int sizePad = 15;
|
||
|
||
/// <summary>
|
||
/// 减少卡顿
|
||
/// </summary>
|
||
protected override CreateParams CreateParams
|
||
{
|
||
get
|
||
{
|
||
CreateParams cp = base.CreateParams;
|
||
cp.ExStyle |= 0x02000000;
|
||
return cp;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 动态缩放
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected override void OnSizeChanged(EventArgs e)
|
||
{
|
||
SuspendLayout();
|
||
this.CloseButton.Left = Width - sizePad - CloseButton.Width;
|
||
this.MaxmizeButton.Left = CloseButton.Left - sizePad - MaxmizeButton.Width;
|
||
this.MinimizeButton.Left = MaxmizeButton.Left - sizePad - MinimizeButton.Width;
|
||
|
||
this.PathTextBox.Width = Width - sizePad - PathTextBox.Left;
|
||
|
||
this.RunButton.Left = Width / 2 + sizePad / 2;
|
||
this.newProgressPanel.Top = Height - sizePad - newProgressPanel.Height;
|
||
this.newProgressPanel.Left = RunButton.Left;
|
||
this.newProgressPanel.Width = Width - sizePad - RunButton.Left;
|
||
this.ProgressPanel.Location = newProgressPanel.Location;
|
||
this.ProgressPanel.Width = newProgressPanel.Width;
|
||
|
||
|
||
this.RunButton.Top = this.ProgressPanel.Top - sizePad - RunButton.Height;
|
||
this.RunButton.Width = Width - sizePad - RunButton.Left;
|
||
|
||
this.InfoLabel.Left = RunButton.Left;
|
||
this.InfoLabel.Top = this.RunButton.Top - sizePad - InfoLabel.Height;
|
||
|
||
this.SizeEstimateLabel.Left = this.RunButton.Left;
|
||
this.SizeEstimateLabel.Top = this.InfoLabel.Top - sizePad - this.SizeEstimateLabel.Height;
|
||
|
||
|
||
this.PostPictureBox.Left = RunButton.Left;
|
||
this.PostPictureBox.Width = this.RunButton.Width;
|
||
this.PostPictureBox.Height = this.SizeEstimateLabel.Top - sizePad - this.PostPictureBox.Top;
|
||
this.PreviousPictureBox.Height = this.PostPictureBox.Height;
|
||
this.PreviousPictureBox.Width = this.PostPictureBox.Left- sizePad - this.PreviousPictureBox.Left;
|
||
|
||
this.KeepOriginalCheckBox.Top = ProgressPanel.Top;
|
||
this.SubFolderCheckBox.Top = this.KeepOriginalCheckBox.Top - 10 - this.SubFolderCheckBox.Height;
|
||
|
||
this.SkipFileSizeTextBox.Top = this.RunButton.Top - this.SkipFileSizeTextBox.Height;
|
||
this.CompressLevelDownButton.Top = this.PostPictureBox.Bottom + sizePad-5;
|
||
this.CompressLevelUpButton.Top = this.CompressLevelDownButton.Top;
|
||
this.CompressLevelTextLabel.Top = this.CompressLevelUpButton.Top + 7;
|
||
this.CompressLevelLabel.Top = this.CompressLevelTextLabel.Bottom - this.CompressLevelLabel.Height-3;
|
||
this.SkipFileSizeTextBox.Top = this.CompressLevelUpButton.Bottom + sizePad-5;
|
||
this.SkipFileSizeLabel.Top = this.SkipFileSizeTextBox.Top+5;
|
||
|
||
this.MaxPixelLimitLabel.Top = this.CompressLevelLabel.Top;
|
||
this.MaxPixelMultiplyLabel.Top = this.MaxPixelLimitLabel.Top;
|
||
this.MaxWidthPixelTextBox.Top = this.CompressLevelUpButton.Top + 3;
|
||
this.MaxHeightPixelTextBox.Top = this.MaxWidthPixelTextBox.Top;
|
||
|
||
|
||
ResumeLayout(false);
|
||
PerformLayout();
|
||
}
|
||
/// <summary>
|
||
/// 点击四边拖拽更改窗口大小的距离距离范围
|
||
/// </summary>
|
||
const float ChangeSizeClickTolerance = 10;
|
||
bool ClickNear(float n1, float n2)
|
||
{
|
||
return Math.Abs(n1 - n2) < ChangeSizeClickTolerance;
|
||
}
|
||
Point moveLocation;
|
||
protected override void OnMouseDown(MouseEventArgs e)
|
||
{
|
||
|
||
this.RunButton.Focus();
|
||
sizeChangeState = SizeChangeState.None;
|
||
if(e.Y > ChangeSizeClickTolerance && e.Y < MinimizeButton.Bottom && e.X < MinimizeButton.Left)
|
||
{
|
||
sizeChangeState = SizeChangeState.Move;
|
||
moveLocation = e.Location;
|
||
return;
|
||
}
|
||
if (ClickNear(0, e.X))
|
||
{
|
||
clickResizeHorizen = ClickResize.Left;
|
||
sizeChangeState = SizeChangeState.ChangeSize;
|
||
}
|
||
else if (ClickNear(Bounds.Width, e.X))
|
||
{
|
||
clickResizeHorizen = ClickResize.Right;
|
||
sizeChangeState = SizeChangeState.ChangeSize;
|
||
}
|
||
else clickResizeHorizen = ClickResize.None;
|
||
|
||
if (ClickNear(0, e.Y))
|
||
{
|
||
clickResizeVertical = ClickResize.Top;
|
||
sizeChangeState = SizeChangeState.ChangeSize;
|
||
}
|
||
else if (ClickNear(Bounds.Height, e.Y))
|
||
{
|
||
clickResizeVertical = ClickResize.Buttom;
|
||
sizeChangeState = SizeChangeState.ChangeSize;
|
||
}
|
||
else clickResizeVertical = ClickResize.None;
|
||
if (sizeChangeState == SizeChangeState.None)
|
||
{
|
||
|
||
base.OnMouseDown(e);
|
||
}
|
||
}
|
||
|
||
protected override void OnMouseMove(MouseEventArgs e)
|
||
{
|
||
ZoomInPictureBox.Visible = false;
|
||
|
||
if (sizeChangeState == SizeChangeState.Move)
|
||
{
|
||
if(this.WindowState != FormWindowState.Normal)
|
||
{
|
||
this.WindowState = FormWindowState.Normal;
|
||
moveLocation = new Point(Width / 2, 10);
|
||
}
|
||
else
|
||
{
|
||
Size size = Bounds.Size;
|
||
Point location = new Point(Bounds.X + e.X - moveLocation.X, Bounds.Y + e.Y - moveLocation.Y);
|
||
Bounds = new Rectangle(location, size);
|
||
}
|
||
}
|
||
else if(sizeChangeState == SizeChangeState.ChangeSize)
|
||
{
|
||
this.WindowState = FormWindowState.Normal;
|
||
Point location = Bounds.Location;
|
||
Size size = Bounds.Size;
|
||
bool changed = false;
|
||
if (clickResizeHorizen == ClickResize.Left)
|
||
{
|
||
location.X = Bounds.X + e.X;
|
||
size.Width = Bounds.Width - e.X;
|
||
changed = true;
|
||
}
|
||
else if (clickResizeHorizen == ClickResize.Right)
|
||
{
|
||
size.Width = e.X;
|
||
changed = true;
|
||
}
|
||
if (clickResizeVertical == ClickResize.Top)
|
||
{
|
||
location.Y = Bounds.Y + e.Y;
|
||
size.Height = Bounds.Height - e.Y;
|
||
changed = true;
|
||
}
|
||
else if (clickResizeVertical == ClickResize.Buttom)
|
||
{
|
||
size.Height = e.Y;
|
||
changed = true;
|
||
}
|
||
if (changed)
|
||
{
|
||
Bounds = new Rectangle(location, size);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bool left = ClickNear(0, e.X);
|
||
bool onHorizon = left || ClickNear(Bounds.Width, e.X);
|
||
bool top = ClickNear(0, e.Y);
|
||
bool onVertical = top || ClickNear(Bounds.Height, e.Y);
|
||
if (onHorizon && onVertical)
|
||
{
|
||
if ((left && top) || ((!left) || (!top))) this.Cursor = Cursors.SizeNWSE;
|
||
else this.Cursor = Cursors.SizeNESW;
|
||
}
|
||
else if (onHorizon)
|
||
{
|
||
this.Cursor = Cursors.SizeWE;
|
||
}
|
||
else if (onVertical)
|
||
{
|
||
this.Cursor = Cursors.SizeNS;
|
||
}
|
||
else this.Cursor = Cursors.Default;
|
||
|
||
|
||
|
||
base.OnMouseMove(e);
|
||
}
|
||
}
|
||
|
||
|
||
protected override void OnMouseUp(MouseEventArgs e)
|
||
{
|
||
if (sizeChangeState!= SizeChangeState.None)
|
||
{
|
||
clickResizeHorizen = ClickResize.None;
|
||
clickResizeVertical= ClickResize.None;
|
||
sizeChangeState = SizeChangeState.None;
|
||
OnSizeChanged(null);
|
||
}
|
||
else base.OnMouseUp(e);
|
||
}
|
||
#endregion
|
||
|
||
#region Drag&Drop
|
||
|
||
|
||
List<string> dragDropFolderPaths = new List<string>();
|
||
|
||
/// <summary>
|
||
/// 改变路径Box的消息
|
||
/// </summary>
|
||
/// <param name="messageText"></param>
|
||
private void ChangePathTextBoxMessage(string messageText)
|
||
{
|
||
if (!string.IsNullOrEmpty(messageText))
|
||
{
|
||
PathTextBox.Text = messageText;
|
||
PathTextBox.ForeColor = Color.Gray;
|
||
}
|
||
}
|
||
|
||
private void Box_DragEnter(object sender, DragEventArgs e)
|
||
{
|
||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||
{
|
||
e.Effect = DragDropEffects.Link;
|
||
}
|
||
else e.Effect = DragDropEffects.None;
|
||
}
|
||
|
||
private void Box_DragDrop(object sender, DragEventArgs e)
|
||
{
|
||
dragDropFolderPaths.Clear();
|
||
Array files = (Array)e.Data.GetData(DataFormats.FileDrop);
|
||
foreach (object file in files)
|
||
{
|
||
FileInfo info = new FileInfo(file.ToString());
|
||
if (info != null && info.Attributes.HasFlag(FileAttributes.Directory))
|
||
{
|
||
dragDropFolderPaths.Add(info.FullName);
|
||
}
|
||
}
|
||
if (dragDropFolderPaths.Count == 0)
|
||
{
|
||
ChangePathTextBoxMessage(Localize.Get("No Folders Droped"));
|
||
return;
|
||
}
|
||
UpdateDropFilePaths();
|
||
UpdateRunButtonText();
|
||
|
||
}
|
||
/// <summary>
|
||
/// 当Drop时更新路径
|
||
/// </summary>
|
||
void UpdateDropFilePaths()
|
||
{
|
||
manager.ReadAllFilePaths(dragDropFolderPaths);
|
||
SetProgressValue(0);
|
||
if (manager.FilesCount == 0)
|
||
{
|
||
MessageBox.Show(Localize.Get("No Images (JPG, PNG, BMP) Found in Folder Droped"), Localize.Get("Warning"));
|
||
PostPictureBox.Image = null;
|
||
PreviousPictureBox.Image = null;
|
||
UpdateDisplayInfo();
|
||
return;
|
||
}
|
||
UpdateDisplayInfo();
|
||
DrawPreviewImg();
|
||
PathTextBox.Lines = dragDropFolderPaths.ToArray();
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region Zoom Picture
|
||
|
||
/// <summary>
|
||
/// 滚轮缩放Zoom框
|
||
/// </summary>
|
||
void OnZoomMouseWheelPre(object sender, MouseEventArgs e)
|
||
{
|
||
|
||
if (e.Delta > 0) ZoomFactor.ZoomPercent *= 0.8;
|
||
else ZoomFactor.ZoomPercent *= 1.25;
|
||
DrawZoomInImage(PreviousPictureBox, e);
|
||
}
|
||
|
||
void OnZoomMouseWheelPost(object sender, MouseEventArgs e)
|
||
{
|
||
|
||
if (e.Delta > 0) ZoomFactor.ZoomPercent *= 0.8;
|
||
else ZoomFactor.ZoomPercent *= 1.25;
|
||
DrawZoomInImage(PostPictureBox, e);
|
||
}
|
||
|
||
void OnZoomMouseMove(object sender, MouseEventArgs e)
|
||
{
|
||
ZoomInPictureBox.Location = new Point(ZoomInPictureBox.Left + e.X + 5, ZoomInPictureBox.Top - ZoomInPictureBox.Height + e.Y - 5);
|
||
}
|
||
|
||
void OnPictureMouseMovePost(object sender, MouseEventArgs e)
|
||
{
|
||
DrawZoomInImage(PostPictureBox, e);
|
||
}
|
||
void OnPictureMouseMovePrevious(object sender, MouseEventArgs e)
|
||
{
|
||
DrawZoomInImage(PreviousPictureBox, e);
|
||
}
|
||
long CpuTime => DateTime.Now.Ticks / 10000;
|
||
long wait = 0;
|
||
void DrawZoomInImage(PictureBox box, MouseEventArgs e)
|
||
{
|
||
long t = CpuTime;
|
||
if (t - wait > 100) wait = t;
|
||
else return;
|
||
|
||
if (PreviousPictureBox.Image == null || PostPictureBox.Image == null)
|
||
{
|
||
ZoomInPictureBox.Visible = false;
|
||
return;
|
||
}
|
||
ZoomInPictureBox.Visible = true;
|
||
ZoomInPictureBox.Location = new Point(box.Left + e.X + 5, box.Top + e.Y - 155);
|
||
ZoomFactor zoomFactor = new ZoomFactor(box.Bounds, e.Location, box.Image.Width, box.Image.Height);
|
||
ZoomInPictureBox.Image = GetZoomImage(zoomFactor);
|
||
}
|
||
|
||
Image GetZoomImage(ZoomFactor factor)
|
||
{
|
||
|
||
Bitmap newBit = new Bitmap(300, 150);
|
||
Rectangle destRectPre = new Rectangle(0, 0, 150, 150);
|
||
Rectangle destRectPost = new Rectangle(150, 0, 150, 150);
|
||
Graphics graphics = Graphics.FromImage(newBit);
|
||
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
|
||
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
|
||
graphics.SetClip(destRectPre);
|
||
Rectangle srcRectPre = factor.GetSourceImage(PreviousPictureBox.Image);
|
||
|
||
graphics.DrawImage(PreviousPictureBox.Image, destRectPre, srcRectPre, GraphicsUnit.Pixel);
|
||
graphics.SetClip(destRectPost);
|
||
Rectangle srcRectPost = factor.GetSourceImage(PostPictureBox.Image);
|
||
graphics.DrawImage(PostPictureBox.Image, destRectPost, srcRectPost, GraphicsUnit.Pixel);
|
||
graphics.Dispose();
|
||
//Debug.WriteLine("srcRectPre = {0}, srcRectPost = {1}", srcRectPre, srcRectPost);
|
||
return newBit;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region UI Event
|
||
/// <summary>
|
||
/// 防止内部修改文字的时候,调用了TextChange事件
|
||
/// </summary>
|
||
bool internalUpdating = false;
|
||
/// <summary>
|
||
/// 在Drop文件之后,初始化Info显示
|
||
/// </summary>
|
||
private void UpdateDisplayInfo()
|
||
{
|
||
internalUpdating = true;
|
||
CompressLevelTextLabel.Text = manager.CompressLevel.ToString();
|
||
MaxHeightPixelTextBox.Text = manager.MaxHeight.ToString();
|
||
MaxWidthPixelTextBox.Text = manager.MaxWidth.ToString();
|
||
|
||
int fileCount = manager.FilesCount;
|
||
if (fileCount > 0)
|
||
{
|
||
newProgressPanel.Text = $"0/{fileCount}";
|
||
newProgressPanel.Refresh();
|
||
manager.SetSkipFileSizeInKB(SkipFileSizeTextBox.Text);
|
||
InfoLabel.Text = string.Format(Localize.Get("Find {0} Imgs , Sum Size = {1}"), manager.FilesCount, manager.GetFileSizeString(manager.PreAllImageSizeinKB));
|
||
|
||
}
|
||
else
|
||
{
|
||
ChangePathTextBoxMessage(Localize.Get("Drag and Drop Folders Here To Start"));
|
||
newProgressPanel.Text = $"0/0";
|
||
newProgressPanel.Refresh();
|
||
SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate: ") + "0KB / 0KB";
|
||
InfoLabel.Text = "";
|
||
}
|
||
internalUpdating = false;
|
||
}
|
||
/// <summary>
|
||
/// 将Form的设置运用到后台程序中去
|
||
/// </summary>
|
||
void ApplySettingsFromForm(bool updateWidthHeight = false)
|
||
{
|
||
manager.SetSkipFileSizeInKB(SkipFileSizeTextBox.Text);
|
||
manager.IncludeSubFolders = SubFolderCheckBox.Checked;
|
||
manager.KeepOriginal = KeepOriginalCheckBox.Checked;
|
||
manager.CompressLevel = int.Parse(CompressLevelTextLabel.Text);
|
||
if(updateWidthHeight)
|
||
{
|
||
manager.MaxWidth = int.Parse(MaxWidthPixelTextBox.Text);
|
||
manager.MaxHeight = int.Parse(MaxHeightPixelTextBox.Text);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 根据Seed绘制一个压缩后的预览图
|
||
/// </summary>
|
||
void DrawPreviewImg()
|
||
{
|
||
if (!manager.GetRandomIndex(seed, out int index))
|
||
{
|
||
//manager没有文件
|
||
PreviousPictureBox.Image = null;
|
||
PostPictureBox.Image = null;
|
||
SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate: ") + "0KB / 0KB";
|
||
return;
|
||
}
|
||
|
||
var rawImage = manager.GetImageAtIndex(index, out string rawFileSize);
|
||
PreviousPictureBox.Image = rawImage;
|
||
|
||
|
||
var newImage = manager.GetCompressedImgAtIndex(index, out string newFileSize, out bool skip, out string errorMessage);
|
||
|
||
|
||
if (skip)
|
||
{
|
||
PostPictureBox.Image = rawImage;
|
||
SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate: ")+$"{rawFileSize} / {rawFileSize}" + Localize.Get("(Skiped)");
|
||
}
|
||
else
|
||
{
|
||
if (newImage == null)
|
||
{
|
||
SizeEstimateLabel.Text = errorMessage;
|
||
PostPictureBox.Image = null;
|
||
return;
|
||
}
|
||
PostPictureBox.Image = newImage;
|
||
SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate: ") +$"{newFileSize} / {rawFileSize}";
|
||
|
||
}
|
||
|
||
ZoomFactor.ZoomPercent = 0.1;
|
||
}
|
||
|
||
|
||
void SkipFileSizeTextBox_FocusLeave(object sender, EventArgs e)
|
||
{
|
||
if (!int.TryParse(SkipFileSizeTextBox.Text, out _))
|
||
SkipFileSizeTextBox.Text = manager.CurrentSkipFileSizeInKB.ToString();
|
||
ApplySettingsFromForm();
|
||
}
|
||
|
||
private void SubFolderCheckBox_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
ApplySettingsFromForm();
|
||
}
|
||
|
||
private void KeepOriginalCheckBox_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
ApplySettingsFromForm();
|
||
}
|
||
int seed = 0;
|
||
private void PreviousPictureBox_Click(object sender, EventArgs e)
|
||
{
|
||
if (manager.FilesCount > 0)
|
||
{
|
||
seed++;
|
||
DrawPreviewImg();
|
||
}
|
||
else seed = 0;
|
||
}
|
||
|
||
private void AfterPictureBox_Click(object sender, EventArgs e)
|
||
{
|
||
if (manager.FilesCount > 0)
|
||
{
|
||
seed--;
|
||
DrawPreviewImg();
|
||
}
|
||
else seed = 0;
|
||
}
|
||
|
||
|
||
|
||
private void CompressLevelTextChanged(bool manuallWidthHeight=false)
|
||
{
|
||
ApplySettingsFromForm(manuallWidthHeight);
|
||
DrawPreviewImg();
|
||
UpdateDisplayInfo();
|
||
|
||
}
|
||
|
||
void MaxHeightPixelTextBox_FocusLeave(object sender, EventArgs e)
|
||
{
|
||
if (internalUpdating) return;
|
||
if (!int.TryParse(MaxHeightPixelTextBox.Text, out _))
|
||
{
|
||
MaxHeightPixelTextBox.Text = manager.MaxHeight.ToString();
|
||
}
|
||
CompressLevelTextChanged(true);
|
||
}
|
||
|
||
|
||
private void TextBox_KeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
if(e.KeyCode == Keys.Enter)
|
||
{
|
||
this.RunButton.Focus();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void MaxWidthPixelTextBox_FocusLeave(object sender, EventArgs e)
|
||
{
|
||
if (internalUpdating) return;
|
||
if (!int.TryParse(MaxWidthPixelTextBox.Text, out _))
|
||
{
|
||
MaxWidthPixelTextBox.Text = manager.MaxWidth.ToString();
|
||
}
|
||
CompressLevelTextChanged(true);
|
||
}
|
||
|
||
|
||
private void CompressLevelDownButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (manager.CompressLevel > 1)
|
||
{
|
||
this.CompressLevelTextLabel.Text = (manager.CompressLevel - 1).ToString();
|
||
CompressLevelTextChanged();
|
||
}
|
||
}
|
||
|
||
private void CompressLevelUpButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (manager.CompressLevel < 10)
|
||
{
|
||
this.CompressLevelTextLabel.Text = (manager.CompressLevel + 1).ToString();
|
||
CompressLevelTextChanged();
|
||
}
|
||
}
|
||
|
||
private void CloseButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (manager.State != RunningState.Running)
|
||
{
|
||
|
||
this.Close();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
//发送结束指令
|
||
manager.Stop();
|
||
while (true)
|
||
{
|
||
if (manager.State != RunningState.Running)
|
||
{
|
||
//确保运行结束后才关闭
|
||
this.Close();
|
||
return;
|
||
}
|
||
else Thread.Sleep(100);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void MaxmizeButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (this.WindowState != FormWindowState.Maximized) this.WindowState = FormWindowState.Maximized;
|
||
else this.WindowState = FormWindowState.Normal;
|
||
}
|
||
|
||
private void MinimizeButton_Click(object sender, EventArgs e)
|
||
{
|
||
this.WindowState = FormWindowState.Minimized;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Run
|
||
|
||
/// <summary>
|
||
/// 用于内部线程调用
|
||
/// </summary>
|
||
/// <param name="percent"></param>
|
||
public delegate void SetProgressValueDelegate(int percent);
|
||
|
||
/// <summary>
|
||
/// 设定进度条
|
||
/// </summary>
|
||
/// <param name="value"></param>
|
||
public void SetProgressValue(int fileCount)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
//从其他线程调用,则在此返回Form线程调用
|
||
SetProgressValueDelegate setProgressValueDelegate = new SetProgressValueDelegate(SetProgressValue);
|
||
this.Invoke(setProgressValueDelegate, fileCount);
|
||
}
|
||
else
|
||
{
|
||
newProgressPanel.ProgressValue =(double)fileCount / manager.FilesCount;
|
||
this.newProgressPanel.Text = $"{fileCount} / {manager.FilesCount}";
|
||
newProgressPanel.Refresh();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 根据RunningState更新按钮文字
|
||
/// </summary>
|
||
public void UpdateRunButtonText()
|
||
{
|
||
switch(manager.State)
|
||
{
|
||
case RunningState.NoFile:
|
||
RunButton.Text = Localize.Get("Waiting for image folders");
|
||
break;
|
||
case RunningState.Running:
|
||
RunButton.Text = Localize.Get("Running, Click to Pause");
|
||
break;
|
||
case RunningState.WaitStop:
|
||
RunButton.Text = Localize.Get("Running, Wait to Pause");
|
||
break;
|
||
case RunningState.AllThreadStoped:
|
||
RunButton.Text = Localize.Get("Paused, Click to Continue");
|
||
break;
|
||
case RunningState.Finished:
|
||
RunButton.Text = Localize.Get("Done");
|
||
break;
|
||
case RunningState.Ready:
|
||
RunButton.Text = Localize.Get("Ready");
|
||
break;
|
||
default:
|
||
RunButton.Text = Localize.Get("Run");
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 点击Run之后运行
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void RunButton_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
if (manager.State == RunningState.Running)
|
||
{
|
||
manager.Stop();
|
||
}
|
||
else if (manager.State == RunningState.Ready || manager.State == RunningState.AllThreadStoped)
|
||
{
|
||
manager.RunAllCompress();
|
||
}
|
||
else //(manager.State == RunningState.Finished)
|
||
{
|
||
RunButton.Text = Localize.Get("Done !!!");
|
||
}
|
||
|
||
UpdateRunButtonText();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 运行完后显示结束报告
|
||
/// </summary>
|
||
internal void ShowReport()
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
//从其他线程调用,则在此返回Form线程调用
|
||
Action ac = new Action(ShowReport);
|
||
this.Invoke(ac);
|
||
}
|
||
else
|
||
{
|
||
CountProgress progress = manager.progress;
|
||
|
||
int minutes = (int)progress.stopwatch.Elapsed.TotalMinutes;
|
||
float seconds = progress.stopwatch.Elapsed.Seconds + (progress.stopwatch.Elapsed.Milliseconds / 100) * 0.1f;
|
||
|
||
string watchString;
|
||
if (minutes > 0) watchString = string.Format(Localize.Get("{0}min {1}s"),minutes,seconds);
|
||
else watchString = string.Format(Localize.Get("{0}s"),seconds);
|
||
|
||
UpdateRunButtonText();
|
||
InfoLabel.Text = string.Format(Localize.Get("Compressed {0}, Skiped {1}, Failed {2}, "), progress.SuccessCount, progress.SkipCount, progress.FailedCount) +
|
||
string.Format(Localize.Get("Time {0}, Compressed Result {1} / {2}"),watchString,manager.GetFileSizeString(progress.PostSizeKBSum), manager.GetFileSizeString(progress.PreSizeKBSum));
|
||
if (progress.FailedInfos.Count > 0)
|
||
{
|
||
MessageBox.Show(string.Join("\n", progress.FailedInfos), Localize.Get("Failed Images Info"));
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
}
|
||
|
||
|
||
}
|