Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - LucaMozzo/WebServerImageCompressor: Utility to compress images on the server with nearly no downtime through duplication · GitHub
Skip to content

Repository files navigation

Image Compressor for Web Servers

Screenshot example

This program has been created to reduce the size on web servers to increase the performance of the page loading. Despite my efforts to make the program as generic as possible, I must admit that it's been designed around my need to batch-compress all the images in one of my customers' Prestashop store.

How it works

The program duplicates the entire tree of the filesystem (starting from the specified path), and converts all the images in the subfolders, keeping the same folder structure.

The idea is that after running the program you could effortlessly switch to the new folder tree with compressed images with nearly no downtime (the time to rename the folder).

Usage

  1. Clone the repo on your web server git clone https://github.com/LucaMozzo/WebServerImageCompressor.git
  2. Enter the folder cd WebServerImageCompressor
  3. Install the libraries:
    python3 -m pip install console-progressbar
    python3 -m pip install PIL
  4. Run e.g. python3 compress.py --source ~/source --output ~/destination --quality 70 --logs ~/failures.log
Argument nameRequiredDescription
--sourceYesThe base directory where the images are
--outputYesThe base directory where the compressed images will be saved
--qualityYesA value 1-100 of the output quality, where 100 is the current quality (no compression)
--logsNoThe file where to write the failures
--threadsNoThe number of threads to use to compress. Defaults to 10

Example of application on a Prestashop store

Prestashop stores the product images in the folder img/p/. So let's assume our prestashop installation is in /var/www/html/prestashop.

We would run the script

python3 compress.py --source /var/www/html/prestashop/img/p/ --output /var/www/html/prestashop/img2/p/ --quality 70 --logs ~/failures.log

Then check the failed images in the output logs file and make adjustments as needed.

To switch between the current images and the compressed ones, we make a folder name swap

mv -r /var/www/html/prestashop/img/ /var/www/html/prestashop/img_old/ && mv -r /var/www/html/prestashop/img2/ /var/www/html/prestashop/img/

Now the original images will be in the folder img_old and the compressed ones in img and will be used by Prestashop for future requests.

Performance considerations

One of the parameters that you can specify is the number of threads. The number of threads needs to be considered carefully before running the script.

More threads =/= less time to complete

Creating a thread has an overhead, so this overhead needs to be worth the effort. For example (using random numbers here) if creating a thread takes 1ms and the operations to be executed also take 1ms, you're probably better off performing those operations sequentially. What I'm saying here is that the time you save by parallelizing the work should be higher than the time spent scheduling the threads.

The experiment

In this section I approach this problem experimentally. I have a folder with multiple subfolders, which ultimately contain 5772 images stored on a HDD. The total size of those images is ~105MB, and their size is variable (from 64x64 to 1000+x1000+).

I then ran the script with multiple number of threads and plotted the execution time against the number of threads and here's the result:

Performance chart

It's clear that going past 15 threads is not worth it in this case, as the time taken is the same, if not higher.

This chart has been made with the average of 3 runs for each number of threads, the data is in the table below:

Number of threadsAverage run time (s)
166.344
240.107
337.052
536.959
1036.694
1526.149
2029.735
3026.316
4029.288
5028.023
6024.855
8524.028
10026.974

It must also be said that the run time is variable. The standard deviation of 5 data points is 2.1663 (relative standard deviation RDS=7.76%)

CPU & Disk utilisation

As you would expect, more operations done in "parallel" mean higher resource utilisation, and more importantly, less resources available for servicing incoming requests (more threads to be scheduled = less CPU time for each of the threads). This means that running this script on a production server with limited resources will slow down the response time, the extent of which has not been measured (as it's extremely variable).

About

Utility to compress images on the server with nearly no downtime through duplication

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages