Czasem dostajemy z jakiegoś źródła, pewną ilość PDFów które następnie musimy np. umieścić na stronie www. Problem pojawia się wtedy, gdy są to przykładowo skany dyplomów i fajniej byłoby mieć je w formacie JPG lub PNG.

Bardzo prosto można przekonwertować jeden plik. Wystarczy skorzystać z biblioteki Imagemagick, korzystając z poniższej składni:

convert -jakies_parametry plik.pdf wynik.jpg

Jak jednak, zrobić to samo dla wielu plików w wielu subkatalogach, a przy tym usunąć plik PDF?

Wystarczy wziąć do tego Rubiego! :) Oczywiście, można to zrobić w bashu, jednak różnicę między skorzystaniem z basha a rubiego, stanowi przenośność tego drugiego rozwiązania.

O ile skrypt basha odpalimy tylko na *nxie, o tyle mając interpreter Rubiego, konwerter odpalimy także pod windowsem.

Nasz skrypt będzie bardzo prosty. Będzie przyjmował dwa opcjonalne argumenty. Pierwszym będzie ścieżka do katalogu, od którego mamy zacząć szukać. Drugim będzie flaga odpowiadająca za ew. usuwanie plików PDF, po skończeniu konwersji.

Zanim jednak to zrobimy, musimy załączyć potrzebne nam biblioteki (oraz “magiczny” komentarz):

# coding: utf-8
require 'find'
require 'fileutils'

Teraz pora na nasze argumenty:

dir = ARGV[0] ? ARGV[0] : '.'
destroy_pdf = ARGV[1] ? ARGV[1] : false

jak nietrudno zauważyć, jeśli ich nie podany, to plików PDF będziemy szukać, w katalogu z którego wywołujemy skrypt, zaś PDFy nie będą po konwersji usuwane.

Następnie musimy sprawdzić, czy ścieżka do katalogu istnieje:

# Jeśli podana sciezka nie jest scieżką poprawną - wywal info o błędzie i
# zakończ skrypt
unless File.directory?(dir)
  puts "Podana ścieżka nie jest poprawna"
  exit 1
end

Następnie “przelatujemy” wszystkie pliki które mamy w katalogu (oraz subkatalogach), dokonujemy konwersji jeśli są to pliki PDF oraz ewentualnie usuwamy PDFa po konwersji:

# Przelatujemy każdy plik w katalogach i subkatalogach naszej sciezki
Find.find(dir) { |f|
  # Olej pliki które nie mają rozszerzenia pdf
  next unless f[f.length-4, 4] == '.pdf'
  # Przekonwertuje na jpg - z taką samą nazwą - tylko rozszerzenie inne
  new_name = "#{f[0, f.length-4]}.jpg"
  # Wyrzuć info o konwersji pliku
  puts "Konwertowanie pliku: #{f}"
  # Konwertujemy...
  system("convert -density 250x250 -quality 90 '#{f}' '#{new_name}'")
  # No i usun pdfa jesli tak podano
  if destroy_pdf
    puts "Usuwanie pliku: #{f}"
    File.delete(f)
  end
}

Warto zwrócić uwagę, że użycie samego convert, bez podania parametrów, sprawi że plik wynikowy będzie miał bardzo kiepską jakość. Aby tak nie było, korzystamy z parametru density, który odpowiada za jakość (DPI) pliku wynikowego. Ustawiamy też jakość na 90%, co w wypadku plików JPG sprawi że będzie bardzo dobrej jakości, przy nie aż tak wielkim rozmiarze.

To by było na tyle. Plik do pobrania: pdf_to_jpg.