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