Skip to content

Instantly share code, notes, and snippets.

@reedho
Last active November 3, 2017 10:42
Show Gist options
  • Save reedho/90049a7e72269a01230e61de36f1e295 to your computer and use it in GitHub Desktop.
Save reedho/90049a7e72269a01230e61de36f1e295 to your computer and use it in GitHub Desktop.
Converting tiff image to png with jai-imageio
;; Why?
;; Because tiff2png fail with warnings & error like below:
;; TIFFReadDirectory: Warning, Unknown field with tag 37724 (0x935c) encountered.
;; TIFFFetchNormalTag: Warning, Incompatible type for "RichTIFFIPTC"; tag ignored.
;; tiff2png error: don't know how to handle PHOTOMETRIC_SEPARATED (001.tif)
;; Below are somewwat dirty way to do conversion with JAI classes
(ns user)
(import 'java.io.File
'javax.imageio.ImageIO
'javax.imageio.IIOImage
'java.awt.image.BufferedImage
'java.awt.Color)
(comment
;; com.github.jaiimageio.impl.plugins.tiff.TIFFImageReader
(-> (ImageIO/getImageReadersByFormatName "tiff")
iterator-seq
first)
;; com.sun.imageio.plugins.png.PNGImageWriter
(-> (ImageIO/getImageWritersByFormatName "png")
iterator-seq
first)
)
(defn convert!
[x]
(let [in-file (File. x)
out-file (File. (clojure.string/replace x #"tif$" "png"))
in-bi (ImageIO/read in-file)
out-bi (BufferedImage. (.getWidth in-bi) (.getHeight in-bi)
BufferedImage/TYPE_BYTE_GRAY)
]
(.drawImage
(.createGraphics out-bi) in-bi 0 0 java.awt.Color/WHITE nil)
(ImageIO/write out-bi "png" out-file)))
;; This version is 10 times faster than the above one.
(defn faster-convert!
[x]
(let [input-file (File. x)
output-file (File. (clojure.string/replace x #"tif$" "png"))
input-buffered-image (ImageIO/read input-file)
width (.getWidth input-buffered-image)
height (.getHeight input-buffered-image)
gray-buffered-image (BufferedImage.
width
height
BufferedImage/TYPE_BYTE_GRAY)
op1 (doto (java.awt.image.ColorConvertOp.
(java.awt.color.ColorSpace/getInstance
java.awt.color.ColorSpace/CS_GRAY)
nil)
(.filter input-buffered-image gray-buffered-image))
output-file-stream (java.io.FileOutputStream. output-file)
image-output-stream (ImageIO/createImageOutputStream output-file-stream)
output-writer (doto (-> (ImageIO/getImageWritersByFormatName "png")
iterator-seq
first)
(.setOutput image-output-stream)
(.write nil ;; IIOMetadata
(IIOImage. gray-buffered-image ;; input-buffered-image
nil ;; thumbnails
nil ;; IIOMetadata
)
nil ;; ImageWriteParam
))
]
(.flush image-output-stream)
(.dispose output-writer)
(.close image-output-stream)
(.close output-file-stream)
))
;; More info
;; This is actually used for converting hafs downloaded from qurancomplex.gov.sa
;; Start lein from terminal like below so when we connect from cider, it will have full
;; cider experience.
;; lein update-in :dependencies conj \[org.clojure/tools.nrepl\ \"0.2.12\"\ \:exclusions\ \[org.clojure/clojure\]\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.16.0-SNAPSHOT\"\] -- update-in : assoc :jvm-opts \[\"-Xmx3g\"\] -- try com.github.jai-imageio/jai-imageio-core
(comment
(for [i (range 30)]
(println
(str "wget http://download.qurancomplex.gov.sa/dm/hafs/tif/"
(format "tif_%03d_%03d.zip" (+ 1 (* i 20)) (+ 20 (* i 20))))))
(doall (map (fn [x] (time (convert! x)))
(for [i (range 41 61)] (format "%03d.tif" i))))
;; Parallel conversion
;; This will Use as much thread as pmap allowed, e.g. numberOfCpu + 2
;; but need more memory and will throw OOM error
(doall (pmap (fn [x] (time (convert! x)))
(for [i (range 21 41)] (format "%03d.tif" i))))
;; This is how we limit the number of parallel
;; processing will occur at a time, 3 in this case.
(doseq [xs (partition-all 4 (range 401 581))]
(pmap (fn [x]
(time (do (convert2! x)
(println "done for" x))))
(map #(format "%03d.tif" %) xs)))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment