Fork me on GitHub
#clojure
<
2019-10-13
>
andy.fingerhut01:10:45

And (def myfn (partial foo "bar")) is copying a pointer/reference to the value of foo, not all of the code of foo.

Santiago07:10:45

I'm trying to rotate an image with a transparent background an arbitrary amount of degrees (e.g. 261), and I don't care if I lose the corners of the image (they're empty anyways). I've found collage, ez-image and imgsclr but all seem to only support rotating in multiples of 90. Rotating and saving the image to disk are the only things I need. Any ideas?

kulminaator08:10:51

because rotating fixed pixels 261 degrees is a bit harder 🙂

kulminaator08:10:35

if i'd have to do it i'd probably implement it myself... just for the educational ride 🙂

yuhan08:10:35

@slack.jcpsantiago I believe clojure2d has a way to do that using the underlying Java Graphics2D library, however the API is not so friendly for doing pure image transformations

kulminaator09:10:42

yep. should be possible just to tell graphics2d to draw a rotated image on an offscreen image buffer and capture the result from there

kulminaator09:10:03

doesn't really look that hard

kulminaator09:10:23

not sure about the outcome quality though, should probably check it out before you invest much time on it 🙂

Alexander Heldt09:10:27

Now I want to implement that, just for fun

Alexander Heldt09:10:21

It's really fun to work with linear algebra, which I assume would do the trick

yuhan09:10:26

(ns scratch
  (:require
   [clojure2d.core :as c2d]
   [ :as io])
  (:import [java.awt Graphics2D]
           [java.awt.image BufferedImage]
           [javax.imageio ImageIO]))

(defn rotate-around-center
  [img degrees]
  (let [w   (.getWidth img)
        h   (.getHeight img)]
    (c2d/with-canvas-> (c2d/canvas w h)
      (c2d/translate (/ w 2) (/ h 2))
      (c2d/rotate (* degrees (/ Math/PI 180)))
      (c2d/translate (- (/ w 2)) (- (/ h 2)))
      (c2d/image img)
      (c2d/get-image))))


(-> ""
  (io/as-url)
  (ImageIO/read)
  (rotate-around-center 261)
  (ImageIO/write "png" (io/as-file "out.png")))

yuhan09:10:26

that was quite painful 😶 gave up on wrangling with Graphics2D interop directly

Santiago13:10:21

wow wasn't expecting this to need such low level code, thanks for the interest guys

yuhan14:10:03

might be worth a PR to one of the above libraries to add arbitrary rotation support 🙂

Santiago14:10:49

I think so 😉 there's imagez and collage and others

Santiago14:10:05

@qythium that seems to the trick for me, but clojure2d seems to be discarding background transparency? source code says "Canvas is transparent by default." hum trying to figure that out, then need to figure out how to pay you a beer 😄

Santiago14:10:21

this is what I'm trying to rotate

yuhan14:10:43

transparency works on my end, how are you reading the image?

yuhan14:10:57

Oh, I'm on version 1.2.0-SNAPSHOT of clojure2d, looks like they made a breaking change to the default canvas transparency

Santiago14:10:30

ah let me try

yuhan14:10:38

you can probably add an optional argument to the (c2d/canvas) call

Santiago14:10:46

works with the snapshot version

Santiago14:10:55

nice thanks a lot 😄

yuhan14:10:34

look how much simpler it is in Python though:

from PIL import Image
Image.open("airplane_small.png").rotate(261).save("out.png")

Santiago14:10:01

facepalm yeah, I'm really shocked this doesn't exist in a library

andy.fingerhut16:10:50

It almost must exist in some Java library somewhere, but I don't have enough knowledge of existing libraries to suggest one.

chrisn17:10:33

https://github.com/cnuernber/libpython-clj and do it in clojure-python to your hearts content 🙂.

Santiago20:10:05

haha cool but no thank you

Santiago06:10:56

btw here's where all the code went into https://github.com/jcpsantiago/controltower Thanks again @qythium app makes sense now haha

yuhan06:10:31

Looks great! There's probably a much cleaner way of doing it without pulling in a large dependency as clojure2d, which is mostly wrappers around the underlying java.awt libraries - I just didn't feel like dealing with the interop

Santiago07:10:28

😅 I don't know Java at all, so for now your solution is the only I understand