3

I want an user to draw something. I will rotate that image many times and I will save each file to a folder. A template is img<degree>.png, for example img24.png is the original image rotated by 24 degree. It's like using Rotate tool, set it to 24 degree and export it with default sittings.

The problem is that every time I rotate and export to png the files getting bigger and bigger. When the original file is 100x100 & 380B, the 9th file is 413x412 2,47KB. I want the images to stay at the same size (100x100 in the above example).

(define (degrees-to-radians degrees) (/ (* degrees *pi*) 180))
(define (script-fu-rotate-and-save in-image in-drawable directory-name) ; degree)

  (let ((ind 0) (x 0) (y 0))
    (while (< ind 361)
      (set! x (car (gimp-image-width in-image)))
      (set! y (car (gimp-image-height in-image)))
      (gimp-item-transform-rotate in-drawable (degrees-to-radians ind) FALSE (/ x 2) (/ y 2))
      (file-png-save-defaults 1 in-image in-drawable (string-append directory-name "/img" (number->string ind) ".png") (string-append directory-name "/temp.png"))
      (set! ind (+ ind 45))
    )
  )
    ;(gimp-displays-flush) ; show changes on image
)
(script-fu-register
  "script-fu-rotate-and-save" ;name
  "rotate and save"
  "Rotates and saves"
  "me"
  "copyrights"
  "today"
  ""
  SF-IMAGE "image-main" 0
  SF-DRAWABLE "drawable-main" 0
  SF-DIRNAME "directory-name" ""
  ;SF-ADJUSTMENT "label" '(value lower upper step_inc page_inc digits type)
  ;SF-ADJUSTMENT "degree" '(1 1 360 1 1 0 0)
)
(script-fu-menu-register "script-fu-rotate-and-save" "<Image>/Rotate and save")
Darek Nędza
  • 1,420
  • 1
  • 12
  • 19

2 Answers2

3

If you rotate a rectangular image, you must either obtain a slightly larger image, or clip off some of that data. Often the area of interest is in fact roughly circular and the corners either background or transparent. However it's unlikely that a rotate algorithm will make that decision for you.

If you iteratively rotate, you not only get an accumulation of size, you also get an accumulation or error because pixels don't match (to see how to suppress this effect, look up rotatebyshear, in the binary image library (here). So the image will start to blur. So you need to always start from your original image, and apply the total rotation.

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
0

If you compare gimp-item-transform-rotate to its - now deprecated - predecessor, you will notice that it has an additional paramter called clip-result, with four possible values (the number in parens is the numeric value of the option):

  • TRANSFORM-RESIZE-ADJUST (0)
  • TRANSFORM-RESIZE-CLIP (1)
  • TRANSFORM-RESIZE-CROP (2)
  • TRANSFORM-RESIZE-CROP-WITH-ASPECT (3)

The current gimp-item-* API get the value from the current context, gimp-context-set-transform-resize is used to set the value you desire.

The default is TRANSFORM-RESIZE-ADJUST (0) - this enlarges the layer on every rotate, and if you rotate the same layer over and over again, the results become bigger and bigger.

You want to try TRANSFORM-RESIZE-CLIP (1) - this clips the rotated layer to the original size.

The remaining two options are a bit harder to understand - there you definitely want to have a look at the user manual. These options are common to the transform tools, btw.

The issue with error accumulation, as indicate in Malcolm's answer, remains. you definitely want to rotate a copy of the original layer by the accumulated angle, instead of rotating the same layer over and over again.