Skip to content

Instantly share code, notes, and snippets.

@nodename
Created December 20, 2011 07:25
Show Gist options
  • Save nodename/1500647 to your computer and use it in GitHub Desktop.
Save nodename/1500647 to your computer and use it in GitHub Desktop.
My first Clojure test! Create an image, save it as a PNG file with a custom metadata string, and read back the string from the file header
(import '(java.awt.image BufferedImage))
(import '(javax.imageio ImageIO IIOImage))
(import '(javax.imageio.stream FileImageOutputStream))
(import '(com.sun.imageio.plugins.png PNGMetadata PNGImageReader))
(import '(java.io ByteArrayOutputStream File))
;; See the following document for requirements
;; for upper- and lower-case letters in the four-letter chunk name:
;; http://en.wikipedia.org/wiki/Portable_Network_Graphics#.22Chunks.22_within_the_file
(def generator-chunk-name "gnTr")
(def image-file-name "test.png")
(defn get-png-imagewriter
"Return an ImageWriter for PNG images"
[]
(let [iterator (ImageIO/getImageWritersBySuffix "png")]
(if-not (.hasNext iterator)
(throw (Exception. "No image writer for PNG")))
(.next iterator)))
(def imagewriter (get-png-imagewriter))
(def bi (BufferedImage. 16 16 BufferedImage/TYPE_INT_ARGB))
(def g (.createGraphics bi))
;; use g
(.drawLine g 0 0 10 10)
(.drawLine g 0 15 15 0)
;; (def output-bytes (ByteArrayOutputStream. ))
;; (.setOutput imagewriter (ImageIO/createImageOutputStream output-bytes))
(def output (FileImageOutputStream. (File. image-file-name)))
(.setOutput imagewriter output)
(defn make-generator-metadata
"Create a PNGMetadata containing generator-string in its generator header chunk"
[generator-string]
(let [png-metadata (PNGMetadata.)]
(.add (.unknownChunkType png-metadata) generator-chunk-name)
(.add (.unknownChunkData png-metadata) (.getBytes generator-string))
png-metadata))
(def metadata (make-generator-metadata "This is the generator"))
(defn write-image
[writer image metadata]
(let [iio-image (IIOImage. image nil nil)]
(.setMetadata iio-image metadata)
(.write writer nil iio-image nil)))
(write-image imagewriter bi metadata)
(.flush output)
(.close output)
(.dispose imagewriter)
;; now reopen the file and read the header
(def input-stream (ImageIO/createImageInputStream (File. image-file-name)))
(defn get-imagereader
[inputstream]
(let [iterator (ImageIO/getImageReaders inputstream)]
(if-not (.hasNext iterator)
(throw (Exception. "No image reader found for stream")))
(.next iterator)))
(def imagereader (get-imagereader input-stream))
(.setInput imagereader input-stream true)
(def image-index 0)
(def input-metadata (.getImageMetadata imagereader image-index))
(defn get-generator-string
"Get the generator string from a PNGMetadata"
[png-metadata]
(let [dataArrayList (.unknownChunkData png-metadata)
typeArrayList (.unknownChunkType png-metadata)]
(loop [i 0]
(cond
(>= i (.size dataArrayList))
""
(= (.get typeArrayList i) generator-chunk-name)
(String. (.get dataArrayList i))
:else
(recur (+ i 1))))))
(def input-generator (get-generator-string input-metadata))
(println input-generator)
@rafaeldelboni
Copy link

rafaeldelboni commented Apr 22, 2022

Hey man I know this been 11 years, but I was doing a POC to check if was possible to generate images using clojure and graalvm and I used this Gist as the base, thanks.

BTW it worked:
https://github.com/rafaeldelboni/graalvm-generate-png

@nodename
Copy link
Author

Cool, I don't remember posting this gist at all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment