Skip to content

Commit 0a86365

Browse files
committed
transform first from regular then from original #14
1 parent 15a978f commit 0a86365

File tree

4 files changed

+175
-6
lines changed

4 files changed

+175
-6
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
project/target
2-
media/*
2+
media/original/*
3+
media/regular/*

project/Cargo.lock

+86
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ authors = ["Dmitriy Belyaev <[email protected]>"]
77
opencv = { git = "git://github.com/kali/opencv-rust" }
88
iron = "*"
99
regex = "0.1"
10+
rexiv2 = "0.3"
1011
lazy_static = "0.1.*"

project/src/main.rs

+86-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extern crate lazy_static;
33
extern crate opencv;
44
extern crate iron;
55
extern crate regex;
6+
extern crate rexiv2;
67

78
use opencv::core as cv;
89
use opencv::types::{VectorOfint, VectorOfuchar};
@@ -29,12 +30,14 @@ fn main() {
2930
match regex.captures(&req.url.path.join("/")) {
3031
Some(cap) => {
3132
let ext = cap.at(3).unwrap();
32-
let path = format!("{}{}.{}", MEDIA_DIRECTORY.to_string(), cap.at(2).unwrap(), ext);
33-
if !Path::new(&path).exists() {
33+
let path_regular = format!("{}regular/{}.{}", MEDIA_DIRECTORY.to_string(), cap.at(2).unwrap(), ext);
34+
let path_original = format!("{}original/{}.{}", MEDIA_DIRECTORY.to_string(), cap.at(2).unwrap(), ext);
35+
36+
if !Path::new(&path_original).exists() {
3437
return Ok(Response::with((iron::status::NotFound, "Image not found")));
3538
}
3639

37-
return handle_image(cap.at(1).unwrap(), &path, ext);
40+
return handle_image(cap.at(1).unwrap(), &path_original, &path_regular, ext);
3841
},
3942
None => Ok(Response::with((iron::status::NotFound, "Invalid url"))),
4043
}
@@ -43,7 +46,7 @@ fn main() {
4346
Iron::new(handler).http("0.0.0.0:3000").unwrap();
4447
}
4548

46-
fn handle_image(filters: &str, path: &str, ext: &str) -> IronResult<Response> {
49+
fn handle_image(filters: &str, path_original: &str, path_regular: &str, ext: &str) -> IronResult<Response> {
4750
let splitted: Vec<&str> = filters.split("+").collect();
4851
let mut operations: Vec<Transformation> = Vec::new();
4952
for entry in &splitted {
@@ -57,6 +60,13 @@ fn handle_image(filters: &str, path: &str, ext: &str) -> IronResult<Response> {
5760
}
5861
}
5962

63+
let path: &str;
64+
if is_regular_can_be_used(&operations, path_regular) {
65+
path = path_regular;
66+
} else {
67+
path = path_original;
68+
}
69+
6070
let mut buffer = VectorOfuchar::new();
6171
let mut mat = highgui::imread(path, highgui::IMREAD_UNCHANGED).unwrap();
6272

@@ -76,6 +86,39 @@ fn handle_image(filters: &str, path: &str, ext: &str) -> IronResult<Response> {
7686
Ok(Response::with((content_type, status::Ok, buffer.to_vec())))
7787
}
7888

89+
fn is_regular_can_be_used(operations: &Vec<Transformation>, path_regular: &str) -> bool {
90+
if Path::new(&path_regular).exists() {
91+
return match rexiv2::Metadata::new_from_path(path_regular) {
92+
Ok(meta) => {
93+
let width = meta.get_pixel_width();
94+
let height = meta.get_pixel_height();
95+
let mut result = false;
96+
97+
for operation in operations {
98+
match operation.is_regular_can_be_used(width, height) {
99+
Cache::NOT_AFFECT => {
100+
continue;
101+
},
102+
Cache::NOT_APPLIED => {
103+
result = false;
104+
break;
105+
},
106+
Cache::APPLIED => {
107+
result = true;
108+
break;
109+
}
110+
}
111+
}
112+
113+
result
114+
},
115+
Err(err) => false
116+
}
117+
}
118+
119+
return false;
120+
}
121+
79122
#[derive(Debug)]
80123
enum Transformation {
81124
Resize {
@@ -97,8 +140,17 @@ enum Transformation {
97140
}
98141
}
99142

143+
enum Cache {
144+
APPLIED, // return if image can be based on regular
145+
NOT_APPLIED, // cannot be based on regular
146+
NOT_AFFECT // has no affect for image size
147+
}
148+
100149
trait TransformationTrait {
101150
fn apply(&self, mat: &cv::Mat) -> cv::Mat;
151+
152+
// Return true if regular image can be read for this transformation
153+
fn is_regular_can_be_used(&self, width: i32, height: i32) -> Cache;
102154
}
103155

104156
impl TransformationTrait for Transformation {
@@ -161,7 +213,7 @@ impl TransformationTrait for Transformation {
161213
};
162214
}
163215
return cv::Mat::rect(&resized, rect).unwrap();
164-
}
216+
},
165217
Transformation::CropCoordinates { x1, y1, x2, y2 } => {
166218
let rect = cv::Rect {
167219
x: x1,
@@ -173,6 +225,35 @@ impl TransformationTrait for Transformation {
173225
}
174226
}
175227
}
228+
fn is_regular_can_be_used(&self, regular_width: i32, regular_height: i32) -> Cache {
229+
match *self {
230+
Transformation::Resize { height, width } => {
231+
let condition: bool;
232+
if height.is_some() && width.is_some() {
233+
condition = regular_width >= width.unwrap() && regular_height >= height.unwrap();
234+
} else if height.is_some() {
235+
condition = regular_height >= height.unwrap();
236+
} else {
237+
condition = regular_width >= width.unwrap();
238+
}
239+
240+
if condition {
241+
return Cache::APPLIED;
242+
} else {
243+
return Cache::NOT_APPLIED;
244+
}
245+
},
246+
Transformation::CropCoordinates { x1, y1, x2, y2 } => Cache::NOT_APPLIED,
247+
Transformation::Crop { height, width } => {
248+
if regular_width >= width && regular_height >= height {
249+
return Cache::APPLIED;
250+
} else {
251+
return Cache::NOT_APPLIED;
252+
}
253+
},
254+
Transformation::Rotate { degrees } => Cache::NOT_AFFECT
255+
}
256+
}
176257
}
177258

178259
fn create_operation(entry: &str) -> Option<Transformation> {

0 commit comments

Comments
 (0)