Panda3D
|
00001 // Filename: imageTrans.cxx 00002 // Created by: drose (19Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "imageTrans.h" 00016 #include "string_utils.h" 00017 #include "pystub.h" 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: ImageTrans::Constructor 00021 // Access: Public 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 ImageTrans:: 00025 ImageTrans() : ImageFilter(true) { 00026 set_program_description 00027 ("This program reads an image file and writes a similar " 00028 "image file to the output. It can implicitly convert from one image " 00029 "file format to another; it uses the extension of the output filename " 00030 "to specify the destination file format."); 00031 00032 add_option 00033 ("chan", "channels", 50, 00034 "Elevate (or truncate) the image to the indicated number of channels. " 00035 "This may be 1, 2, 3, or 4. You may also specify one of the keywords " 00036 "l, la, rgb, or rgba, respectively, or any of the keywords r, g, b, or " 00037 "a to extract out just the indicated channel as a single grayscale " 00038 "image.", 00039 &ImageTrans::dispatch_channels, NULL, &_channels); 00040 00041 add_option 00042 ("cscale", "r,g,b[,a]", 50, 00043 "Apply the indicated color scale to each pixel of the image.", 00044 &ImageTrans::dispatch_color, &_has_color_scale, &_color_scale); 00045 00046 _channels = C_default; 00047 _color_scale.set(1.0f, 1.0f, 1.0f, 1.0f); 00048 } 00049 00050 //////////////////////////////////////////////////////////////////// 00051 // Function: ImageTrans::run 00052 // Access: Public 00053 // Description: 00054 //////////////////////////////////////////////////////////////////// 00055 void ImageTrans:: 00056 run() { 00057 switch (_channels) { 00058 case C_default: 00059 break; 00060 00061 case C_l: 00062 case C_la: 00063 case C_rgb: 00064 case C_rgba: 00065 _image.set_num_channels((int)_channels); 00066 break; 00067 00068 case C_r: 00069 _image.make_grayscale(1.0, 0.0, 0.0); 00070 _image.remove_alpha(); 00071 break; 00072 00073 case C_g: 00074 _image.make_grayscale(0.0, 1.0, 0.0); 00075 _image.remove_alpha(); 00076 break; 00077 00078 case C_b: 00079 _image.make_grayscale(0.0, 0.0, 1.0); 00080 _image.remove_alpha(); 00081 break; 00082 00083 case C_a: 00084 extract_alpha(); 00085 break; 00086 } 00087 00088 if (_has_color_scale) { 00089 if (_color_scale[0] != 1.0f || 00090 _color_scale[1] != 1.0f || 00091 _color_scale[2] != 1.0f) { 00092 for (int yi = 0; yi < _image.get_y_size(); ++yi) { 00093 for (int xi = 0; xi < _image.get_x_size(); ++xi) { 00094 LRGBColord rgb = _image.get_xel(xi, yi); 00095 _image.set_xel(xi, yi, 00096 rgb[0] * _color_scale[0], 00097 rgb[1] * _color_scale[1], 00098 rgb[2] * _color_scale[2]); 00099 } 00100 } 00101 } 00102 if (_image.has_alpha() && _color_scale[3] != 1.0f) { 00103 for (int yi = 0; yi < _image.get_y_size(); ++yi) { 00104 for (int xi = 0; xi < _image.get_x_size(); ++xi) { 00105 PN_stdfloat a = _image.get_alpha(xi, yi); 00106 _image.set_alpha(xi, yi, a * _color_scale[3]); 00107 } 00108 } 00109 } 00110 } 00111 00112 write_image(); 00113 } 00114 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: ImageTrans::dispatch_channels 00117 // Access: Private, Static 00118 // Description: Interprets the -chan parameter. 00119 //////////////////////////////////////////////////////////////////// 00120 bool ImageTrans:: 00121 dispatch_channels(const string &opt, const string &arg, void *var) { 00122 Channels *ip = (Channels *)var; 00123 if (cmp_nocase(arg, "l") == 0) { 00124 (*ip) = C_l; 00125 } else if (cmp_nocase(arg, "la") == 0) { 00126 (*ip) = C_la; 00127 } else if (cmp_nocase(arg, "rgb") == 0) { 00128 (*ip) = C_rgb; 00129 } else if (cmp_nocase(arg, "rgba") == 0) { 00130 (*ip) = C_rgba; 00131 } else if (cmp_nocase(arg, "r") == 0) { 00132 (*ip) = C_r; 00133 } else if (cmp_nocase(arg, "g") == 0) { 00134 (*ip) = C_g; 00135 } else if (cmp_nocase(arg, "b") == 0) { 00136 (*ip) = C_b; 00137 } else if (cmp_nocase(arg, "a") == 0) { 00138 (*ip) = C_a; 00139 } else { 00140 int value; 00141 if (!string_to_int(arg, value)) { 00142 nout << "Invalid parameter for -" << opt << ": " 00143 << arg << "\n"; 00144 return false; 00145 } 00146 if (value < 1 || value > 4) { 00147 nout << "Number of channels must be one of 1, 2, 3, or 4.\n"; 00148 return false; 00149 } 00150 (*ip) = (Channels)value; 00151 } 00152 00153 return true; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: ImageTrans::extract_alpha 00158 // Access: Private 00159 // Description: Extracts out just the alpha channel and stores it as 00160 // a grayscale image. 00161 //////////////////////////////////////////////////////////////////// 00162 void ImageTrans:: 00163 extract_alpha() { 00164 if (!_image.has_alpha()) { 00165 nout << "Source image does not have an alpha channel!\n"; 00166 _image.make_grayscale(); 00167 _image.fill(); 00168 return; 00169 } 00170 00171 _image.make_grayscale(); 00172 for (int y = 0; y < _image.get_y_size(); y++) { 00173 for (int x = 0; x < _image.get_x_size(); x++) { 00174 _image.set_gray_val(x, y, _image.get_alpha_val(x, y)); 00175 } 00176 } 00177 _image.remove_alpha(); 00178 } 00179 00180 00181 int main(int argc, char *argv[]) { 00182 // A call to pystub() to force libpystub.so to be linked in. 00183 pystub(); 00184 00185 ImageTrans prog; 00186 prog.parse_command_line(argc, argv); 00187 prog.run(); 00188 return 0; 00189 }