-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSmartImageScale.cc
More file actions
123 lines (113 loc) · 4.7 KB
/
SmartImageScale.cc
File metadata and controls
123 lines (113 loc) · 4.7 KB
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
#include"SmartImageScale.hpp"
#include"Seam.hpp"
#include"Image.hpp"
using namespace std;
SmartImageScale::SmartImageScale(const std::vector<unsigned char>& input, int width) :
origImage(input, width),
workImage(input, width){}
SmartImageScale::SmartImageScale(const std::vector<unsigned char>& input, const std::vector<unsigned char>& mask, int width) :
origImage(input, width),
origMask(mask, width),
workMask(mask, width),
workImage(input, width){}
auto SmartImageScale::verticalAdjust(int N) -> void{
Timer t;
if( N == 0 ) return;
t.tick();
cout << " adjusting " << N << " vertical seams" << endl;
Seam seam(workImage, workMask);
t.ticktock("SIS Seam Constructor");
if( N > 0){
seam.addNSeams(N);
t.ticktock("SIS Seam adding");
} else{
seam.removeNSeams(-N);
t.ticktock("SIS Seam removeing");
}
workImage = seam.resultImage();
if(workMask.size() > 0) workMask = seam.resultMask();
t.ticktock("SIS Seam taking result");
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
}
auto SmartImageScale::horizontalAdjust(int N) -> void{
Timer t;
if( N == 0 ) return;
t.tick();
cout << " adjusting " << N << " horisontal seams" << endl;
workImage = static_cast<ImageRGBA<unsigned char>&& >(workImage.rotate90CCW());
if(workMask.size() > 0) workMask = static_cast<ImageRGBA<unsigned char>&& >(workMask.rotate90CCW());
t.ticktock("SIS rotatingCCW");
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
Seam seam(workImage, workMask);
t.ticktock("SIS Seam Constructor");
if( N > 0){
seam.addNSeams(N);
t.ticktock("SIS Seam adding");
} else{
seam.removeNSeams(-N);
t.ticktock("SIS Seam removeing");
}
workImage = seam.resultImage();
if(workMask.size() > 0) workMask = seam.resultMask();
t.ticktock("SIS Seam taking result");
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
workImage = static_cast<ImageRGBA<unsigned char>&& >(workImage.rotate90CW());
if(workMask.size() > 0) workMask = static_cast<ImageRGBA<unsigned char>&& >(workMask.rotate90CW());
t.ticktock("SIS rotatingCCW");
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
}
auto SmartImageScale::scale(int desiredWidth, int desiredHeight) -> ImageRGBA<unsigned char> {
Timer t;
cout << "SIS SmartScaling image from " << origImage.getWidth() << 'x' << origImage.getHeight();
cout << " to " << desiredWidth << 'x' << desiredHeight << endl;
FP originalAspectRatio = ((FP)origImage.getWidth()) / origImage.getHeight();
FP desiredAspectRatio = ((FP)desiredWidth) / desiredHeight;
t.tick();
if(desiredWidth == origImage.getWidth() && desiredHeight == origImage.getHeight()){
}
else if(desiredWidth >= origImage.getWidth() && desiredHeight >= origImage.getHeight()){
//expanding image
int w, h;
if(originalAspectRatio > desiredAspectRatio){
//scale to match the desired width
w = desiredWidth;
h = desiredWidth/originalAspectRatio;
} else{
//scale to match the desired height
w = desiredHeight*originalAspectRatio;
h = desiredHeight;
}
cout << "SIS Bilinear expanding to " << w << 'x' << h << endl;
workImage = static_cast<ImageRGBA<unsigned char>&& >(workImage.scaleBilinear(w, h));
if(workMask.size() > 0) workMask = static_cast<ImageRGBA<unsigned char>&& >(workMask.scaleBilinear(w, h));
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
t.ticktock("SIS Bilinear scaleing ");
verticalAdjust(desiredWidth - w); //add
horizontalAdjust(desiredHeight - h); //add
} else if(desiredWidth <= origImage.getWidth() && desiredHeight <= origImage.getHeight()){
int w, h;
if(originalAspectRatio < desiredAspectRatio){
//scale to match the desired width
w = desiredWidth;
h = desiredWidth/originalAspectRatio;
} else{
//scale to match the desired height
w = desiredHeight*originalAspectRatio;
h = desiredHeight;
}
cout << "SIS Bilinear shrinking to " << w << 'x' << h << endl;
workImage = static_cast<ImageRGBA<unsigned char>&& >(workImage.scaleBilinear(w, h));
if(workMask.size() > 0) workMask = static_cast<ImageRGBA<unsigned char>&& >(workMask.scaleBilinear(w, h));
cout << workImage.getWidth() << "x" << workImage.getHeight() << endl;
t.ticktock("SIS Bilinear scaleing ");
verticalAdjust(desiredWidth - w); //remove
horizontalAdjust(desiredHeight - h); //remove
} else if(desiredWidth < origImage.getWidth() && desiredHeight > origImage.getHeight()){
verticalAdjust(desiredWidth - origImage.getWidth()); //remove
horizontalAdjust(desiredHeight - origImage.getHeight()); //add
} else if(desiredWidth > origImage.getWidth() && desiredHeight < origImage.getHeight()){
horizontalAdjust(desiredHeight - origImage.getHeight()); //add
verticalAdjust(desiredWidth - origImage.getWidth()); //remove
}
return workImage;
}