Panda3D
 All Classes Functions Variables Enumerations
imageTrans.cxx
1 // Filename: imageTrans.cxx
2 // Created by: drose (19Jun00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "imageTrans.h"
16 #include "string_utils.h"
17 #include "pystub.h"
18 
19 ////////////////////////////////////////////////////////////////////
20 // Function: ImageTrans::Constructor
21 // Access: Public
22 // Description:
23 ////////////////////////////////////////////////////////////////////
24 ImageTrans::
25 ImageTrans() : ImageFilter(true) {
26  set_program_brief("apply transformations to an image file");
27  set_program_description
28  ("This program reads an image file and writes a similar "
29  "image file to the output. It can implicitly convert from one image "
30  "file format to another; it uses the extension of the output filename "
31  "to specify the destination file format.");
32 
33  add_option
34  ("chan", "channels", 50,
35  "Elevate (or truncate) the image to the indicated number of channels. "
36  "This may be 1, 2, 3, or 4. You may also specify one of the keywords "
37  "l, la, rgb, or rgba, respectively, or any of the keywords r, g, b, or "
38  "a to extract out just the indicated channel as a single grayscale "
39  "image.",
40  &ImageTrans::dispatch_channels, NULL, &_channels);
41 
42  add_option
43  ("cscale", "r,g,b[,a]", 50,
44  "Apply the indicated color scale to each pixel of the image.",
45  &ImageTrans::dispatch_color, &_has_color_scale, &_color_scale);
46 
47  add_option
48  ("flip", "", 50,
49  "Flip the image vertically.",
50  &ImageTrans::dispatch_none, &_flip);
51 
52  add_option
53  ("mirror", "", 50,
54  "Reverse the image horizontally.",
55  &ImageTrans::dispatch_none, &_mirror);
56 
57  add_option
58  ("cw", "", 50,
59  "Rotate the image 90 degrees clockwise.",
60  &ImageTrans::dispatch_none, &_cw);
61 
62  add_option
63  ("ccw", "", 50,
64  "Rotate the image 90 degrees counter-clockwise.",
65  &ImageTrans::dispatch_none, &_ccw);
66 
67  _channels = C_default;
68  _color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: ImageTrans::run
73 // Access: Public
74 // Description:
75 ////////////////////////////////////////////////////////////////////
76 void ImageTrans::
77 run() {
78  switch (_channels) {
79  case C_default:
80  break;
81 
82  case C_l:
83  case C_la:
84  case C_rgb:
85  case C_rgba:
86  _image.set_num_channels((int)_channels);
87  break;
88 
89  case C_r:
90  _image.make_grayscale(1.0, 0.0, 0.0);
91  _image.remove_alpha();
92  break;
93 
94  case C_g:
95  _image.make_grayscale(0.0, 1.0, 0.0);
96  _image.remove_alpha();
97  break;
98 
99  case C_b:
100  _image.make_grayscale(0.0, 0.0, 1.0);
101  _image.remove_alpha();
102  break;
103 
104  case C_a:
105  extract_alpha();
106  break;
107  }
108 
109  if (_has_color_scale) {
110  if (_color_scale[0] != 1.0f ||
111  _color_scale[1] != 1.0f ||
112  _color_scale[2] != 1.0f) {
113  for (int yi = 0; yi < _image.get_y_size(); ++yi) {
114  for (int xi = 0; xi < _image.get_x_size(); ++xi) {
115  LRGBColorf rgb = _image.get_xel(xi, yi);
116  _image.set_xel(xi, yi,
117  rgb[0] * _color_scale[0],
118  rgb[1] * _color_scale[1],
119  rgb[2] * _color_scale[2]);
120  }
121  }
122  }
123  if (_image.has_alpha() && _color_scale[3] != 1.0f) {
124  for (int yi = 0; yi < _image.get_y_size(); ++yi) {
125  for (int xi = 0; xi < _image.get_x_size(); ++xi) {
126  PN_stdfloat a = _image.get_alpha(xi, yi);
127  _image.set_alpha(xi, yi, a * _color_scale[3]);
128  }
129  }
130  }
131  }
132 
133  bool transpose = false;
134  if (_cw) {
135  _flip = !_flip;
136  transpose = !transpose;
137  }
138  if (_ccw) {
139  _mirror = !_mirror;
140  transpose = !transpose;
141  }
142  if (_flip || _mirror || transpose) {
143  _image.flip(_mirror, _flip, transpose);
144  }
145 
146  write_image();
147 }
148 
149 ////////////////////////////////////////////////////////////////////
150 // Function: ImageTrans::dispatch_channels
151 // Access: Private, Static
152 // Description: Interprets the -chan parameter.
153 ////////////////////////////////////////////////////////////////////
154 bool ImageTrans::
155 dispatch_channels(const string &opt, const string &arg, void *var) {
156  Channels *ip = (Channels *)var;
157  if (cmp_nocase(arg, "l") == 0) {
158  (*ip) = C_l;
159  } else if (cmp_nocase(arg, "la") == 0) {
160  (*ip) = C_la;
161  } else if (cmp_nocase(arg, "rgb") == 0) {
162  (*ip) = C_rgb;
163  } else if (cmp_nocase(arg, "rgba") == 0) {
164  (*ip) = C_rgba;
165  } else if (cmp_nocase(arg, "r") == 0) {
166  (*ip) = C_r;
167  } else if (cmp_nocase(arg, "g") == 0) {
168  (*ip) = C_g;
169  } else if (cmp_nocase(arg, "b") == 0) {
170  (*ip) = C_b;
171  } else if (cmp_nocase(arg, "a") == 0) {
172  (*ip) = C_a;
173  } else {
174  int value;
175  if (!string_to_int(arg, value)) {
176  nout << "Invalid parameter for -" << opt << ": "
177  << arg << "\n";
178  return false;
179  }
180  if (value < 1 || value > 4) {
181  nout << "Number of channels must be one of 1, 2, 3, or 4.\n";
182  return false;
183  }
184  (*ip) = (Channels)value;
185  }
186 
187  return true;
188 }
189 
190 ////////////////////////////////////////////////////////////////////
191 // Function: ImageTrans::extract_alpha
192 // Access: Private
193 // Description: Extracts out just the alpha channel and stores it as
194 // a grayscale image.
195 ////////////////////////////////////////////////////////////////////
196 void ImageTrans::
197 extract_alpha() {
198  if (!_image.has_alpha()) {
199  nout << "Source image does not have an alpha channel!\n";
200  _image.make_grayscale();
201  _image.fill();
202  return;
203  }
204 
205  _image.make_grayscale();
206  for (int y = 0; y < _image.get_y_size(); y++) {
207  for (int x = 0; x < _image.get_x_size(); x++) {
208  _image.set_gray_val(x, y, _image.get_alpha_val(x, y));
209  }
210  }
211  _image.remove_alpha();
212 }
213 
214 
215 int main(int argc, char *argv[]) {
216  // A call to pystub() to force libpystub.so to be linked in.
217  pystub();
218 
219  ImageTrans prog;
220  prog.parse_command_line(argc, argv);
221  prog.run();
222  return 0;
223 }
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
A program to read an image file and write an equivalent image file, possibly performing some minor op...
Definition: imageTrans.h:28
This is the base class for a program that reads an image file, operates on it, and writes another ima...
Definition: imageFilter.h:29
void write_image()
Writes the generated to the user&#39;s specified output filename.
Definition: imageWriter.I:23