-
Notifications
You must be signed in to change notification settings - Fork 157
/
Copy pathEx2MyFirstGUIApp.scala
143 lines (121 loc) · 4.19 KB
/
Ex2MyFirstGUIApp.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright (c) 2011-2019 Jarek Sacha. All Rights Reserved.
*
* Author's e-mail: jpsacha at gmail.com
*/
package opencv_cookbook.chapter01
import opencv_cookbook.OpenCVUtils.toBufferedImage
import org.bytedeco.opencv.global.opencv_core._
import org.bytedeco.opencv.global.opencv_imgcodecs._
import org.bytedeco.opencv.global.opencv_imgproc._
import org.bytedeco.opencv.opencv_core._
import java.awt.Cursor._
import java.io.File
import javax.swing.ImageIcon
import scala.swing.Dialog.Message.Error
import scala.swing.FileChooser.Result.Approve
import scala.swing._
/**
* The last section in the chapter 1 of the Cookbook demonstrates how to create a simple GUI application.
*
* The Cookbook is using Qt GUI Toolkit. This example is using Scala Swing to create an similar application.
*
* The application has two buttons on the left "Open Image" and "Process".
* The opened image is displayed in the middle.
* When "Process" button is pressed the image is flipped upside down and its red and blue channels are swapped.
*
* Unlike most of other examples in this module, this example is done the Scala way,
* without regard to for direct porting to Java. A Java equivalent is in [[opencv_cookbook.chapter01.Ex2MyFirstGUIAppJava]].
*/
object Ex2MyFirstGUIApp extends SimpleSwingApplication {
private lazy val fileChooser = new FileChooser(new File("."))
def top: Frame = new MainFrame {
title = "My First GUI Scala App"
// Variable for holding loaded image
var image: Option[Mat] = None
//
// Define actions
//
// Action performed when "Open Image" button is pressed
private val openImageAction = Action("Open Image") {
cursor = getPredefinedCursor(WAIT_CURSOR)
try {
// Load image and update display. If new image was not loaded do nothing.
openImage() match {
case Some(mat) =>
val bi = toBufferedImage(mat)
image = Some(mat)
imageView.icon = new ImageIcon(bi)
processAction.enabled = true
case None =>
}
} finally {
cursor = getPredefinedCursor(DEFAULT_CURSOR)
}
}
// Action performed when "Process" button is pressed
private lazy val processAction = Action("Process") {
cursor = getPredefinedCursor(WAIT_CURSOR)
try {
// Process and update image display if image is loaded
image match {
case Some(mat) =>
processImage(mat)
val bi = toBufferedImage(mat)
imageView.icon = new ImageIcon(bi)
case None =>
Dialog.showMessage(null, "Image not opened", title, Error)
}
} finally {
cursor = getPredefinedCursor(DEFAULT_CURSOR)
}
}
processAction.enabled = false
//
// Create UI
//
// Component for displaying the image
lazy val imageView = new Label
// Create button panel
private val buttonsPanel = new GridPanel(rows0 = 0, cols0 = 1) {
contents += new Button(openImageAction)
contents += new Button(processAction)
vGap = 5
}
// Layout frame contents
contents = new BorderPanel() {
// Action buttons on the left
add(new FlowPanel(buttonsPanel), BorderPanel.Position.West)
// Image display in the center
private val imageScrollPane = new ScrollPane(imageView) {
preferredSize = new Dimension(640, 480)
}
add(imageScrollPane, BorderPanel.Position.Center)
}
// Mark for display in the center of the screen
centerOnScreen()
}
/** Ask user for location and open new image. */
private def openImage(): Option[Mat] = {
// Ask user for the location of the image file
if (fileChooser.showOpenDialog(null) != Approve) {
return None
}
// Load the image
val path = fileChooser.selectedFile.getAbsolutePath
val newImage = imread(path)
if (!newImage.empty()) {
Some(newImage)
} else {
Dialog.showMessage(null, "Cannot open image file: " + path, top.title, Error)
None
}
}
/** Process image in place. */
private def processImage(src: Mat): Unit = {
// Flip upside down
flip(src, src, 0)
// Swap red and blue channels
cvtColor(src, src, COLOR_BGR2RGB)
}
}