Skip to content

Instantly share code, notes, and snippets.

@money4honey
Last active August 27, 2016 00:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save money4honey/6a4e460c79a2831c200820b64399d19e to your computer and use it in GitHub Desktop.
Save money4honey/6a4e460c79a2831c200820b64399d19e to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
using Ini;
namespace ImgCompressor
{
public partial class Form1 : Form
{
static NumericUpDown numUpDown1, numUpDown2;
static List<string> newFiles = new List<string>();
static string imgFolder = "", iniPath;
static int imgQuality = 0;
static double sizeBefore, sizeAfter;
static Stopwatch time;
static IniFile ini;
public Form1()
{
InitializeComponent();
// static links
numUpDown1 = numericUpDown1;
numUpDown2 = numericUpDown2;
iniPath = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, "settings.ini");
ini = new IniFile(iniPath);
imgFolder = ini.IniReadValue("Main", "imgFolder");
if (imgFolder.Length > 0) {
textBox1.Text = imgFolder;
}
}
private void button1_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
imgFolder = folderBrowserDialog1.SelectedPath;
textBox1.Text = imgFolder;
if (imgFolder.Length > 0) {
ini.IniWriteValue("Main", "imgFolder", imgFolder);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (imgFolder.Length > 0) {
newFiles.Clear();
time = Stopwatch.StartNew();
ThreadFactory tf = new ThreadFactory();
tf.Start();
}
else {
MessageBox.Show("Please select a folder");
}
}
class ThreadFactory
{
int count = 0;
object locker = new object();
public void Start()
{
if (!Directory.Exists(imgFolder + "\\compressed")) {
Directory.CreateDirectory(imgFolder + "\\compressed");
}
imgQuality = Convert.ToInt32(numUpDown1.Value);
string[] files = Directory.GetFiles(imgFolder);
sizeBefore = countFilesSize(files);
int maxThreads = Convert.ToInt32(numUpDown2.Value);
ThreadPool.SetMaxThreads(maxThreads, maxThreads);
ThreadPool.QueueUserWorkItem(threadFunc, files);
}
void threadFunc(Object threadContext)
{
lock (locker)
{
string[] files = (string[])threadContext;
string file = files[count];
string newPath = imgFolder + "\\compressed\\" + getFileName(imgFolder, file);
newFiles.Add(newPath);
try
{
if (!File.Exists(newPath))
{
bool compressed = CompressJpeg(newPath, Image.FromFile(file, true), 80);
if (!compressed) {
throw new Exception();
}
}
}
catch {
if (!File.Exists(newPath)) {
File.Copy(file, newPath);
}
}
count++;
if (count < files.Length) {
ThreadPool.QueueUserWorkItem(threadFunc, files);
}
else {
time.Stop();
sizeAfter = countFilesSize(newFiles.ToArray());
double diff = Math.Round((sizeBefore - sizeAfter) / 1024.0, 2);
MessageBox.Show("Done!\n\nYou save " + diff.ToString() + " mb\n\nElapsed time: " + time.Elapsed.TotalMilliseconds.ToString("0.00 ms"));
}
}
}
}
public static bool CompressJpeg(string path, Image img, int quality)
{
if (path.ToLower().Contains(".jpg"))
{
if (quality < 0 || quality > 100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
// JPEG image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
img.Dispose();
return true;
}
else {
return false;
}
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
static string getFileName(string pathToFolder, string pathToFile)
{
return pathToFile.Replace(pathToFolder, "").Replace("\\", "");
}
static double getFileSize(string path)
{
if (File.Exists(path)) {
return Convert.ToDouble(new FileInfo(path).Length / 1024);
}
else { return 0; }
}
static double countFilesSize(string[] files) {
double sum = 0;
foreach (string file in files) {
sum += getFileSize(file);
}
return sum;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment