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 }