SHOW:
|
|
- or go back to the newest paste.
1 | ||
2 | ||
3 | /* compile with | |
4 | * | |
5 | - | * g++ -Wall test.cpp `pkg-config vipsCC --cflags --libs` |
5 | + | * g++ -Wall test_image_resize.cpp `pkg-config vipsCC --cflags --libs` |
6 | * | |
7 | */ | |
8 | ||
9 | #include <iostream> | |
10 | #include <fstream> | |
11 | #include <sstream> | |
12 | #include <string> | |
13 | #include <algorithm> | |
14 | ||
15 | #include <vips/vips> | |
16 | #include <vips/vips.h> | |
17 | ||
18 | #define PROGRESSIVE 1 | |
19 | ||
20 | /* Macro to convert integer to string */ | |
21 | #define SSTR( x ) dynamic_cast< std::ostringstream & > ( ( std::ostringstream() << std::dec << x ) ).str() | |
22 | ||
23 | ||
24 | ||
25 | /** | |
26 | * | |
27 | * @param inputname : absolute path of the file. [ /home/vinod/test_code/test.cpp ] | |
28 | * @param path : the path. [ /home/vinod/test_code ] | |
29 | * @param name : the name. [ test ] | |
30 | * @param ext : the extension. [ cpp ] | |
31 | */ | |
32 | void split_path_name_ext(std::string &inputname, std::string &path, std::string &name, std::string &ext) | |
33 | { | |
34 | path = inputname.substr(0, inputname.find_last_of("/")); | |
35 | name = inputname.substr(inputname.find_last_of("/") + 1, | |
36 | inputname.find_last_of(".") - inputname.find_last_of("/") - 1); | |
37 | ext = inputname.substr(inputname.find_last_of(".") + 1); | |
38 | return; | |
39 | } | |
40 | ||
41 | /** | |
42 | * | |
43 | * @param ifilename : name of the image file to be resized. | |
44 | * @return 0 on success. | |
45 | */ | |
46 | int image_resize(std::string& ifilename) | |
47 | { | |
48 | ||
49 | ||
50 | int height[]={1080,720,480,360,240}; | |
51 | int n_files = sizeof(height)/sizeof(height[0]); | |
52 | std::string path , name , ext; | |
53 | split_path_name_ext(ifilename,path,name,ext); | |
54 | ||
55 | /* The vips7 C++ interface doesn't support the open mode we need. | |
56 | */ | |
57 | - | if (vips_foreign_load (ifilename.c_str (), &x, |
57 | + | |
58 | - | "access", VIPS_ACCESS_SEQUENTIAL, NULL)){ |
58 | + | std::transform(ext.begin(),ext.end(),ext.begin(),::tolower); |
59 | ||
60 | if (vips_foreign_load (ifilename.c_str (), &x, NULL)){ | |
61 | std::cout<<"cant load - "<<ifilename<<std::endl; | |
62 | return -1; | |
63 | } | |
64 | ||
65 | ||
66 | ||
67 | vips::VImage im (x); | |
68 | im._ref->close_on_delete = 1; | |
69 | double aspect_ratio = double(im.Xsize()) / double(im.Ysize()); | |
70 | ||
71 | vips::VImage * out; | |
72 | out = new vips::VImage [n_files + 1]; | |
73 | out[0] = im; | |
74 | int k=0; | |
75 | for(int i=0; i < n_files ; i++) | |
76 | { | |
77 | int input_height = out[i].Ysize(); | |
78 | int target_height = height[i]; | |
79 | int target_width = (int(target_height * aspect_ratio) /2 )*2; | |
80 | ||
81 | /* I need not upsample */ | |
82 | if (target_height > input_height) { | |
83 | out[i + 1] = out[i]; | |
84 | continue; | |
85 | } | |
86 | ||
87 | double scale = target_height / (double) input_height; | |
88 | /* Shrink to integer factor first - This is faster | |
89 | */ | |
90 | int shrink_factor = floor (1.0 / scale); | |
91 | if ((1.0 / scale) > 2.0) | |
92 | { | |
93 | out[i] = out[i].shrink (double (shrink_factor), double (shrink_factor)); | |
94 | - | int tile_width; |
94 | + | |
95 | - | int tile_height; |
95 | + | |
96 | - | int nlines; |
96 | + | |
97 | */ | |
98 | - | VipsImage * temp; |
98 | + | if(ext.find("png")!=std::string::npos ){ |
99 | - | vips_get_tile_size (out[i].image (), &tile_width, &tile_height, &nlines); |
99 | + | int tile_width; |
100 | - | if (vips_tilecache (out[i].image (), &temp, |
100 | + | int tile_height; |
101 | - | "tile_width", out[i].Xsize (), |
101 | + | int nlines; |
102 | - | "tile_height", 10, |
102 | + | VipsImage * temp; |
103 | - | "max_tiles", (nlines * 2) / 10, |
103 | + | vips_get_tile_size (out[i].image (), &tile_width, &tile_height, &nlines); |
104 | - | "access", VIPS_ACCESS_SEQUENTIAL, |
104 | + | if (vips_tilecache (out[i].image (), &temp, |
105 | - | "threaded", TRUE, NULL)) |
105 | + | "tile_width", out[i].Xsize (), |
106 | - | vips_error_exit ("can't cache"); |
106 | + | "tile_height", 10, |
107 | - | out[i+1] = vips::VImage(temp); |
107 | + | "max_tiles", (nlines * 2) / 10, |
108 | - | out[i+1]._ref->close_on_delete = 1; |
108 | + | "access", VIPS_ACCESS_SEQUENTIAL, |
109 | - | out[i+1]._ref->addref (out[i]._ref); |
109 | + | "threaded", TRUE, NULL)) |
110 | vips_error_exit ("can't cache"); | |
111 | out[i+1] = vips::VImage(temp); | |
112 | out[i+1]._ref->close_on_delete = 1; | |
113 | out[i+1]._ref->addref (out[i]._ref); | |
114 | } | |
115 | else | |
116 | out[i+1] = out[i]; | |
117 | ||
118 | /* Use affine transform to get to the required size */ | |
119 | int height_aft_shrink = floor (input_height / shrink_factor); | |
120 | ||
121 | scale = target_height / (double) height_aft_shrink; | |
122 | out[i+1] = out[i+1].affinei ("bicubic", scale, 0, 0, scale, | |
123 | 0, 0, 0, 0, target_width, target_height); | |
124 | ||
125 | /* Apply Sharpening Filter */ | |
126 | if (target_width < 150 || target_height < 150) | |
127 | { | |
128 | /* Sharpening Filter*/ | |
129 | vips::VIMask sharpen_filter (3, 3, 8, 0, | |
130 | -1, -1, -1, -1, 16, -1, -1, -1, -1); | |
131 | out[i+1] = out[i+1].conv (sharpen_filter); | |
132 | } | |
133 | ||
134 | ||
135 | std::string ofilename = path + "/" + name + "_" + SSTR(target_height) + ".jpg"; | |
136 | std::cout << "starting save for " << ofilename << " ..." << std::endl; | |
137 | if (vips_foreign_save ((VipsImage *) (out[i+1].image ()), | |
138 | (char *) ofilename.c_str (), | |
139 | "interlace", PROGRESSIVE, NULL)) | |
140 | { | |
141 | std::cout << "Error in saving file: " << ofilename << std::endl; | |
142 | std::cout << vips_error_buffer () << std::endl; | |
143 | } | |
144 | else | |
145 | k++; | |
146 | ||
147 | } | |
148 | delete [] out; | |
149 | return 0; | |
150 | ||
151 | } | |
152 | ||
153 | int | |
154 | main (int argc, char **argv) | |
155 | { | |
156 | if (vips_init (argv[0])) | |
157 | vips_error_exit ("unable to init"); | |
158 | ||
159 | GOptionContext *context; | |
160 | GError *error = NULL; | |
161 | ||
162 | context = g_option_context_new ("- test prog"); | |
163 | ||
164 | g_option_context_add_group (context, vips_get_option_group ()); | |
165 | ||
166 | if (!g_option_context_parse (context, &argc, &argv, &error)) | |
167 | { | |
168 | - | |
168 | + | |
169 | - | std::string filelist("/home/vinod/simple_tests/filelist.txt"); |
169 | + | |
170 | - | std::ifstream filehandle(filelist.c_str()); |
170 | + | |
171 | - | while(!filehandle.eof()) |
171 | + | |
172 | - | { |
172 | + | |
173 | - | std::string ifilename; |
173 | + | |
174 | - | getline(filehandle, ifilename); |
174 | + | |
175 | - | if(ifilename.size()!=0) |
175 | + | |
176 | ||
177 | - | image_resize(ifilename); |
177 | + | |
178 | ||
179 | ||
180 | ||
181 | for(int i=1;i<20;i++) { | |
182 | std::string filelist("/home/vinod/simple_tests/filelist.txt"); | |
183 | std::ifstream filehandle(filelist.c_str()); | |
184 | while(!filehandle.eof()) | |
185 | { | |
186 | std::string ifilename; | |
187 | getline(filehandle, ifilename); | |
188 | if(ifilename.size()!=0) | |
189 | { | |
190 | image_resize(ifilename); | |
191 | } | |
192 | } | |
193 | filehandle.close(); | |
194 | } | |
195 | ||
196 | return 0; | |
197 | } |