Advertisement
vinvinod

Resizing with vips

Dec 25th, 2013
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.19 KB | None | 0 0
  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);
  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.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement