add image watermark rendering support
This commit is contained in:
parent
37bbe3f398
commit
b83de09f9e
|
@ -1,9 +1,12 @@
|
|||
(ns clj-htmltopdf.watermark
|
||||
(:require
|
||||
[clojure.java.io :as io])
|
||||
(:import
|
||||
[java.io InputStream OutputStream]
|
||||
[org.apache.pdfbox.pdmodel PDDocument PDPage PDPageContentStream PDPageContentStream$AppendMode]
|
||||
[org.apache.pdfbox.pdmodel.common PDRectangle]
|
||||
[org.apache.pdfbox.pdmodel.font PDType1Font PDFont]
|
||||
[org.apache.pdfbox.pdmodel.graphics.image PDImageXObject PDImage]
|
||||
[org.apache.pdfbox.pdmodel.graphics.state PDExtendedGraphicsState]
|
||||
[org.apache.pdfbox.util Matrix]))
|
||||
|
||||
|
@ -24,25 +27,25 @@
|
|||
"courier-oblique" PDType1Font/COURIER_OBLIQUE
|
||||
"courier-boldoblique" PDType1Font/COURIER_BOLD_OBLIQUE})
|
||||
|
||||
(defn render-watermark!
|
||||
[^PDPage page ^PDPageContentStream cs options]
|
||||
(let [font (or (get watermark-fonts (:font options))
|
||||
(get watermark-fonts "helvetica-bold"))
|
||||
font-size (float (or (:font-size options) 36.0))
|
||||
font-color (or (:color options) [0 0 0])
|
||||
text (:text options)
|
||||
text-width (/ (* (.getStringWidth font text) font-size) 1000.0)
|
||||
text-height (/ (* (.getHeight (.getFontBoundingBox (.getFontDescriptor ^PDFont font))) font-size) 1000.0)
|
||||
rotation (float (or (:rotation options) 0))
|
||||
page-size (.getMediaBox page)
|
||||
page-width (.getWidth page-size)
|
||||
page-height (.getHeight page-size)
|
||||
x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
|
||||
y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
|
||||
transform (doto (Matrix.)
|
||||
(.translate x y)
|
||||
(.rotate (Math/toRadians rotation))
|
||||
(.translate (- (/ text-width 2)) (- (/ text-height 2))))]
|
||||
(defn render-text-watermark!
|
||||
[^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
|
||||
(let [font (or (get watermark-fonts (:font options))
|
||||
(get watermark-fonts "helvetica-bold"))
|
||||
font-size (float (or (:font-size options) 36.0))
|
||||
font-color (or (:color options) [0 0 0])
|
||||
text (:text options)
|
||||
text-width (/ (* (.getStringWidth font text) font-size) 1000.0)
|
||||
text-height (/ (* (.getHeight (.getFontBoundingBox (.getFontDescriptor ^PDFont font))) font-size) 1000.0)
|
||||
rotation (float (or (:rotation options) 0))
|
||||
page-size (.getMediaBox page)
|
||||
page-width (.getWidth page-size)
|
||||
page-height (.getHeight page-size)
|
||||
x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
|
||||
y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
|
||||
transform (doto (Matrix.)
|
||||
(.translate x y)
|
||||
(.rotate (Math/toRadians rotation))
|
||||
(.translate (- (/ text-width 2)) (- (/ text-height 2))))]
|
||||
(when (:opacity options)
|
||||
(let [r0 (PDExtendedGraphicsState.)]
|
||||
(.setNonStrokingAlphaConstant r0 (float (:opacity options)))
|
||||
|
@ -54,6 +57,36 @@
|
|||
(.showText cs text)
|
||||
(.endText cs)))
|
||||
|
||||
(defn render-image-watermark!
|
||||
[^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
|
||||
(let [image (PDImageXObject/createFromFileByContent (io/file (:image options)) doc)
|
||||
image-width (.getWidth image)
|
||||
image-height (.getHeight image)
|
||||
rotation (float (or (:rotation options) 0))
|
||||
page-size (.getMediaBox page)
|
||||
page-width (.getWidth page-size)
|
||||
page-height (.getHeight page-size)
|
||||
x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
|
||||
y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
|
||||
transform (doto (Matrix.)
|
||||
(.translate x y)
|
||||
(.scale (or (:scale-x options) 1.0) (or (:scale-y options) 1.0))
|
||||
(.rotate (Math/toRadians rotation))
|
||||
(.translate (- (/ image-width 2)) (- (/ image-height 2))))]
|
||||
(when (:opacity options)
|
||||
(let [r0 (PDExtendedGraphicsState.)]
|
||||
(.setNonStrokingAlphaConstant r0 (float (:opacity options)))
|
||||
(.setGraphicsStateParameters cs r0)))
|
||||
(.transform cs transform)
|
||||
(.drawImage cs image (float 0) (float 0))))
|
||||
|
||||
(defn render-watermark!
|
||||
[^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
|
||||
(cond
|
||||
(:text options) (render-text-watermark! doc page cs options)
|
||||
(:image options) (render-image-watermark! doc page cs options)
|
||||
:else (throw (Exception. "Unknown type of watermark. Either :text or :image should be specified."))))
|
||||
|
||||
(defn write-watermark!
|
||||
[^InputStream pdf ^OutputStream out {:keys [watermark] :as options}]
|
||||
(with-open [doc (PDDocument/load pdf)]
|
||||
|
@ -61,7 +94,7 @@
|
|||
(let [cs (PDPageContentStream. doc page PDPageContentStream$AppendMode/APPEND true true)]
|
||||
(with-open [cs cs]
|
||||
(if (map? watermark)
|
||||
(render-watermark! page cs watermark)
|
||||
(watermark page cs)))))
|
||||
(render-watermark! doc page cs watermark)
|
||||
(watermark doc page cs)))))
|
||||
(.save doc out)
|
||||
out))
|
||||
|
|
Loading…
Reference in a new issue