Created
December 20, 2011 07:25
-
-
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
This file contains 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
(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) |
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
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