5

I want to reduce the quality of a bunch of images at the time. With -q:v x where x is a number between 1 and 30 (the bigger the number, the worse the quality). I'm able to save a lot of space even with x=1. Now, when it comes to process multiple files, I'm stuck.

I've tried these two batch files:

mkdir processed
for f in *.jpg;
    do name=`echo $i | cut -d'.' -f1`;
    echo $name;
    ffmpeg -i $i -q:v 1 processed/$name.jpg;
done

And

mkdir processed
for f in *.jpg;
    do ffmpeg -i "$f" -q:v 1 processed/"${f%.jpg}.jpg"; 
done

Both just create the processed folder but nothing else.

Mofi
  • 46,139
  • 17
  • 80
  • 143
Jorge Anzola
  • 1,165
  • 3
  • 13
  • 33
  • Looks like you are doing this in BASH and not BATCH. The batch-file tag is for Windows Batch Files. – Squashman Feb 05 '16 at 14:14
  • Should the semi-colon be there in the `for` statement? – Gyan Feb 05 '16 at 14:20
  • Oh, damn, I was so wrong. I am indeed doing it in a Windows Batch File. But the code is completely wrong. – Jorge Anzola Feb 05 '16 at 14:24
  • You may be able to use `jpegtran` to losslessly optimize the images, possibly with significant file size savings, without needing to re-encode. The results will of course depend in the files themselves though. – llogan Feb 07 '16 at 00:39

3 Answers3

9

Thanks to @Squashman for pointing out my stupid mistake. This is my solution to the problem for Windows batch script.

mkdir processed
for %%F in (*.jpg) do (
  
    ffmpeg -i "%%F" -q:v 10 "processed\%%F"
)

I got like a 80% of weight reduction.

hoohoo-b
  • 1,141
  • 11
  • 12
Jorge Anzola
  • 1,165
  • 3
  • 13
  • 33
  • 2
    Here is a one liner for mac: `for f in ./*.jpg; do ffmpeg -i $f -q:v 10 processed/$f; done` – Maksim Feb 08 '18 at 20:53
  • 1
    Here is even a more complete one liner: `if [ ! -d processed ]; then mkdir -p processed; else echo folder exists; fi && for f in ./*.jpg; do ffmpeg -i $f -q:v 10 processed/$f; done` – bandito40 May 06 '19 at 01:52
1

for linux you can make this script if all your images are in this directory images

make a script.sh which contains the following code

mkdir images/processed
for f in images/*.jpg images/*.png images/*.jpeg
 do
        ffmpeg -i $f -q:v 10 processed/$f -y
done
Ahmed Magdy
  • 1,054
  • 11
  • 16
0

Here is a solution, using ffmpeg in a python script. More verbose, but therefore easier to read.

from pathlib import Path
import os
suffix = ".jpg"
input_path= Path.home() / "Downloads"
file_paths= [subp for subp in input_path.rglob('*') if  suffix == subp.suffix]
file_paths.sort()

output_path =  Path.home() / "Downloads/processed"
output_path.mkdir(parents=True, exist_ok=True)


for file_p in file_paths:
    input = str(file_p)
    output = str(  output_path / file_p.name  ) 
    command = f"ffmpeg -i {input} -q:v 10 {output}"
    os.system(command)
Kolibril
  • 1,096
  • 15
  • 19