Panda3D
Loading...
Searching...
No Matches
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 */
20ImageTrans::
21ImageTrans() : 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 */
70void ImageTrans::
71run() {
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 */
146bool ImageTrans::
147dispatch_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 */
185void ImageTrans::
186extract_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
204int main(int argc, char *argv[]) {
205 ImageTrans prog;
206 prog.parse_command_line(argc, argv);
207 prog.run();
208 return 0;
209}
This is the base class for a program that reads an image file, operates on it, and writes another ima...
Definition imageFilter.h:26
A program to read an image file and write an equivalent image file, possibly performing some minor op...
Definition imageTrans.h:25
void write_image()
Writes the generated to the user's specified output filename.
Definition imageWriter.I:18
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_...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.