Last active
November 3, 2017 10:42
-
-
Save reedho/90049a7e72269a01230e61de36f1e295 to your computer and use it in GitHub Desktop.
Converting tiff image to png with jai-imageio
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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