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