This commit is contained in:
2026-02-02 21:56:45 +08:00
commit 320550399d
24 changed files with 4551 additions and 0 deletions

239
Compressor/ImgsProcess.cs Normal file
View File

@@ -0,0 +1,239 @@
//#define NoOutput
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Dynamic;
namespace ImageCompressor
{
/// <summary>
/// 一个单独的线程,来批量压缩图片
/// </summary>
class ImgsProcess
{
/// <summary>
/// 这个压缩进程内的所有压缩图片的路径
/// </summary>
ImgPaths[] ImgPaths { get; set; }
/// <summary>
/// 计数当前线程编号用于Debug
/// </summary>
public int threadIndex=-1;
/// <summary>
/// 引用的进度总控
/// </summary>
readonly CountProgress progress;
int currentIndex = 0;
/// <summary>
/// 设定是否要在过程中停止计算,标记为停止后,等待计算停止
/// </summary>
public bool ToStop { get; set; } = false;
/// <summary>
/// 判断是否所有计算已经停止
/// </summary>
public bool Stoped { get; private set; } = false;
/// <summary>
/// 该线程处理的所有图片数量
/// </summary>
public int AllCount { get; private set; }
public ImgsProcess(int index, List<ImgPaths> imgPaths, CountProgress countProgress)
{
threadIndex = index;
ImgPaths = imgPaths.ToArray();
AllCount = ImgPaths.Length;
this.progress = countProgress;
}
/// <summary>
/// 开始时设定所有的压缩参数
/// </summary>
/// <param name="compressLevel"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
public void SetCompressLevel(int compressLevel,int maxWidth, int maxHeight)
{
this.compressLevel = compressLevel;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
}
int compressLevel;
int maxWidth;
int maxHeight;
/// <summary>
/// 用来传递每个Img压缩时候的数据
/// </summary>
class DataPack
{
public DataPack(ImgPaths paths, JPGCompressor compressor)
{
this.compressor = compressor;
this.imgPaths = paths;
}
public JPGCompressor compressor;
public ImgPaths imgPaths;
public byte[] readBytes = null;
public byte[] saveBytes = null;
}
#if DEBUG
double Tick => Math.Round(DateTime.Now.TimeOfDay.TotalSeconds % 1000, 3);
#endif
public void Start()
{
Stoped = false;
ToStop = false;
ResetCountData();
while (currentIndex < AllCount)
{
#if DEBUG
long t1 = progress.stopwatch.ElapsedMilliseconds;
#endif
DataPack dataPack = new DataPack(ImgPaths[currentIndex],new JPGCompressor(compressLevel,maxWidth,maxHeight));
ReadOneImage(dataPack);
CompressCurrent(dataPack);
WriteOneImage(dataPack);
#if DEBUG
long t2 = progress.stopwatch.ElapsedMilliseconds;
#endif
progress.RWLock.AcquireWriterLock(-1);
UpdateCountProgress();
ResetCountData();
Thread.Sleep(25);
progress.RWLock.ReleaseWriterLock();
#if DEBUG
Debug.WriteLine($"thread {threadIndex} count {currentIndex}, from {t1}, used {t2 - t1}");
#endif
currentIndex++;
if (ToStop)
{
Stoped = true;
return;
}
}
Stoped = true;
}
//当前线程运行的结果变量
int successCount = 0;
int failedCount = 0;
List<string> failedPaths = new List<string>();
int skipCount = 0;
long preSizeKB = 0;
long saveSizeKB = 0;
/// <summary>
/// 重置当前线程运行的结果变量
/// </summary>
void ResetCountData()
{
successCount = 0;
failedCount = 0;
failedPaths.Clear();
skipCount = 0;
preSizeKB = 0;
saveSizeKB = 0;
}
/// <summary>
/// 读照片到DataPack
/// </summary>
/// <param name="dataPack"></param>
void ReadOneImage(DataPack dataPack)
{
ImgPaths imgPaths = dataPack.imgPaths;
if(!imgPaths.OriginalFileInfo.Exists)
{
failedCount++;
failedPaths.Add(Localize.Get("Read file missing") + imgPaths.OriginalFileInfo.FullName);
return;
}
preSizeKB += imgPaths.OriginalFileInfo.Length / 1024;
if (FilesManager.IsSkip(imgPaths.OriginalFileInfo))
{
skipCount++;
return;
}
dataPack.readBytes = dataPack.compressor.ReadFileToBytes(imgPaths.OriginalFileInfo, out string error);
if (dataPack.readBytes == null)
{
failedCount++;
failedPaths.Add(error + imgPaths.OriginalFileInfo.FullName);
}
}
/// <summary>
/// 压缩得到文件的Bytes
/// </summary>
/// <param name="dataPack"></param>
void CompressCurrent(DataPack dataPack)
{
if (dataPack.readBytes != null)
{
dataPack.saveBytes = dataPack.compressor.CompressBytes(dataPack.readBytes,out string error);
if(dataPack.saveBytes == null)
{
failedCount++;
failedPaths.Add(error + dataPack.imgPaths.OriginalFileInfo.FullName);
}
}
}
/// <summary>
/// 写Bytes到文件
/// </summary>
/// <param name="dataPack"></param>
void WriteOneImage(DataPack dataPack)
{
if (dataPack.saveBytes != null)
{
bool keepOriginal = dataPack.imgPaths.KeepOriginal;
FileInfo saveFile = keepOriginal ? dataPack.imgPaths.DuplicatedFileInfo : dataPack.imgPaths.OriginalFileInfo;
bool re = dataPack.compressor.SaveCompressBytes(dataPack.saveBytes, saveFile, out string error);
if (re)
{
saveSizeKB += dataPack.saveBytes.LongLength / 1024;
successCount++;
}
else
{
failedCount++;
failedPaths.Add(error + dataPack.imgPaths.DuplicatedFileInfo.FullName);
}
}
}
/// <summary>
/// 将本线程结果更新到progress的结果
/// </summary>
void UpdateCountProgress()
{
if (progress.Finished) return;
progress.SuccessCount += successCount;
progress.FailedCount+= failedCount;
progress.SkipCount += skipCount;
progress.FailedInfos.AddRange(failedPaths);
progress.PreSizeKBSum+= preSizeKB;
progress.PostSizeKBSum += saveSizeKB;
progress.Update();
}
}
}