Mercurial > cgi-bin > hgweb.cgi > ImagePrep
comparison src/name/blackcap/imageprep/RotateDialog.kt @ 3:09dcd475d1bf
Works (prelim tests only).
author | David Barts <n5jrn@me.com> |
---|---|
date | Fri, 17 Jul 2020 11:48:07 -0700 |
parents | 0bded24f746e |
children | 9129ae110146 |
comparison
equal
deleted
inserted
replaced
2:a6f9b51d5e8d | 3:09dcd475d1bf |
---|---|
9 import java.awt.RenderingHints | 9 import java.awt.RenderingHints |
10 import java.awt.event.ActionListener | 10 import java.awt.event.ActionListener |
11 import java.awt.image.BufferedImage | 11 import java.awt.image.BufferedImage |
12 import java.io.File | 12 import java.io.File |
13 import java.io.IOException | 13 import java.io.IOException |
14 import java.util.logging.Level | |
15 import java.util.logging.Logger | |
14 import javax.imageio.ImageIO | 16 import javax.imageio.ImageIO |
15 import javax.swing.* | 17 import javax.swing.* |
16 import kotlin.math.* | 18 import kotlin.math.* |
17 | 19 |
18 class RotateDialog(val file: File, initialImage: BufferedImage) : JDialog(Application.mainFrame) { | 20 class RotateDialog(val file: File, initialImage: BufferedImage) : JDialog(Application.mainFrame) { |
55 /* Theoretically, this should do the rotation in a background thread. | 57 /* Theoretically, this should do the rotation in a background thread. |
56 Practically, that is fraught with difficulties, as it involves | 58 Practically, that is fraught with difficulties, as it involves |
57 manipulating data used by Swing itself. Since the size of the images | 59 manipulating data used by Swing itself. Since the size of the images |
58 being rotated are small, we do it in the foreground. */ | 60 being rotated are small, we do it in the foreground. */ |
59 private fun doRotate(deg: Int) { | 61 private fun doRotate(deg: Int) { |
62 rootPane.defaultButton = null | |
60 // https://stackoverflow.com/questions/15927014/rotating-an-image-90-degrees-in-java | 63 // https://stackoverflow.com/questions/15927014/rotating-an-image-90-degrees-in-java |
64 if (deg % 90 != 0) { | |
65 val barf = "${deg} not a multiple of 90!" | |
66 LOGGER.log(Level.SEVERE, barf) | |
67 throw AssertionError(barf) | |
68 } | |
61 val rad = java.lang.Math.toRadians(deg.toDouble()) | 69 val rad = java.lang.Math.toRadians(deg.toDouble()) |
62 val sinx = sin(rad) | 70 val (w, h) = if (deg % 180 == 0) Pair(image.width, image.height) else Pair(image.height, image.width) |
63 val cosx = cos(rad) | |
64 val w = floor(image.width * cosx + image.height * sinx).toInt() | |
65 val h = floor(image.height * cosx + image.width * sinx).toInt() | |
66 val rotatedImage = BufferedImage(w, h, image.type) | 71 val rotatedImage = BufferedImage(w, h, image.type) |
67 rotatedImage.createGraphics().run { | 72 rotatedImage.createGraphics().run { |
68 translate((w - image.width) / 2, (h - image.height) / 2) | 73 translate((w - image.width) / 2, (h - image.height) / 2) |
69 rotate(rad, image.width.toDouble()/2.0, image.height.toDouble()/2.0) | 74 rotate(rad, image.width.toDouble()/2.0, image.height.toDouble()/2.0) |
70 drawRenderedImage(image, null) | 75 drawRenderedImage(image, null) |
95 add(r180) | 100 add(r180) |
96 add(Box.createHorizontalGlue()) | 101 add(Box.createHorizontalGlue()) |
97 add(r90ccw) | 102 add(r90ccw) |
98 }) | 103 }) |
99 } | 104 } |
105 rootPane.defaultButton = null | |
100 pack() | 106 pack() |
101 } | 107 } |
102 | 108 |
103 companion object Factory { | 109 companion object Factory { |
104 /** | 110 /** |
135 Application.mainFrame.useNormalCursor() | 141 Application.mainFrame.useNormalCursor() |
136 val (image, error) = get() | 142 val (image, error) = get() |
137 if (error != null) | 143 if (error != null) |
138 ioExceptionDialog(Application.mainFrame, input, "read", error) | 144 ioExceptionDialog(Application.mainFrame, input, "read", error) |
139 else if (image != null) | 145 else if (image != null) |
140 RotateDialog(input, image).title = input.getName() | 146 RotateDialog(input, image).run { |
147 title = input.name | |
148 setVisible(true) | |
149 } | |
141 else | 150 else |
142 JOptionPane.showMessageDialog(Application.mainFrame, | 151 JOptionPane.showMessageDialog(Application.mainFrame, |
143 "Image is too small to be scaled.", | 152 "Image is too small to be scaled.", |
144 "Warning", JOptionPane.WARNING_MESSAGE) | 153 "Warning", JOptionPane.WARNING_MESSAGE) |
145 } | 154 } |