🐛 Revert the revert of orientation detection on media

This reverts commit 515cbf7bef.
This commit is contained in:
Andrey Antukh
2025-08-05 22:03:09 +02:00
parent ccc3ca0948
commit e28d2842f6

View File

@@ -10,6 +10,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.media :as cm] [app.common.media :as cm]
[app.common.schema :as sm] [app.common.schema :as sm]
[app.common.schema.openapi :as-alias oapi] [app.common.schema.openapi :as-alias oapi]
@@ -21,6 +22,7 @@
[buddy.core.bytes :as bb] [buddy.core.bytes :as bb]
[buddy.core.codecs :as bc] [buddy.core.codecs :as bc]
[clojure.java.shell :as sh] [clojure.java.shell :as sh]
[clojure.string]
[clojure.xml :as xml] [clojure.xml :as xml]
[cuerdas.core :as str] [cuerdas.core :as str]
[datoteka.fs :as fs] [datoteka.fs :as fs]
@@ -215,6 +217,23 @@
{:width (int width) {:width (int width)
:height (int height)})))])) :height (int height)})))]))
(defn- get-dimensions-with-orientation [^String path]
;; Image magick doesn't give info about exif rotation so we use the identify command
;; If we are processing an animated gif we use the first frame with -scene 0
(let [dim-result (sh/sh "identify" "-format" "%w %h\n" path)
orient-result (sh/sh "identify" "-format" "%[EXIF:Orientation]\n" path)]
(if (and (= 0 (:exit dim-result))
(= 0 (:exit orient-result)))
(let [[w h] (-> (:out dim-result)
str/trim
(clojure.string/split #"\s+")
(->> (mapv #(Integer/parseInt %))))
orientation (-> orient-result :out str/trim)]
(case orientation
("6" "8") {:width h :height w} ; Rotated 90 or 270 degrees
{:width w :height h})) ; Normal or unknown orientation
nil)))
(defmethod process :info (defmethod process :info
[{:keys [input] :as params}] [{:keys [input] :as params}]
(let [{:keys [path mtype] :as input} (check-input input)] (let [{:keys [path mtype] :as input} (check-input input)]
@@ -234,13 +253,17 @@
:code :media-type-mismatch :code :media-type-mismatch
:hint (str "Seems like you are uploading a file whose content does not match the extension." :hint (str "Seems like you are uploading a file whose content does not match the extension."
"Expected: " mtype ". Got: " mtype'))) "Expected: " mtype ". Got: " mtype')))
;; For an animated GIF, getImageWidth/Height returns the delta size of one frame (if no frame given (let [{:keys [width height]}
;; it returns size of the last one), whereas getPageWidth/Height always return the full size of (or (get-dimensions-with-orientation (str path))
;; any frame. (do
(assoc input (l/warn "Failed to read image dimensions with orientation; falling back to im4java"
:width (.getPageWidth instance) {:path path})
:height (.getPageHeight instance) {:width (.getPageWidth instance)
:ts (dt/now)))))) :height (.getPageHeight instance)}))]
(assoc input
:width width
:height height
:ts (dt/now)))))))
(defmethod process-error org.im4java.core.InfoException (defmethod process-error org.im4java.core.InfoException
[error] [error]