Init
This commit is contained in:
239
Compressor/ImgsProcess.cs
Normal file
239
Compressor/ImgsProcess.cs
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user