00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "imageFixHiddenColor.h"
00016 #include "string_utils.h"
00017 #include "pystub.h"
00018
00019
00020
00021
00022
00023
00024 ImageFixHiddenColor::
00025 ImageFixHiddenColor() : ImageFilter(true) {
00026 set_program_description
00027 ("This program is designed to fix the color channels of an "
00028 "alpha-cutout image, making the \"color\" of the invisible part of the "
00029 "image consistent with the rest of the image. It does this by "
00030 "analyzing the RGB values of the image where alpha == 1, and using the "
00031 "average of these values as the overall image color, which it then "
00032 "applies to the image wherever alpha == 0. When the alpha value is "
00033 "neither 1 nor 0, the pixel is ignored.\n\n"
00034
00035 "This process is important for applications that filter the texture "
00036 "size down by averaging neighboring pixels. If the color under the "
00037 "alpha == 0 pixels is very different from the color elsewhere, this "
00038 "kind of filtering can have a visible effect on the image's color, even "
00039 "where alpha != 0.");
00040
00041 add_option
00042 ("alpha", "filename", 0,
00043 "Specifies a separate filename that will be used in lieu of the "
00044 "alpha channel on the source image. If this file has an alpha "
00045 "channel, that alpha channel is used; otherwise, the grayscale "
00046 "value of the image is used.",
00047 &ImageFixHiddenColor::dispatch_filename, NULL, &_alpha_filename);
00048
00049 add_option
00050 ("opaque", "alpha", 0,
00051 "Specifies the minimum alpha value (in the range of 0 to 1) for a "
00052 "pixel to be considered fully opaque. The default is 1.",
00053 &ImageFixHiddenColor::dispatch_double, NULL, &_min_opaque_alpha);
00054
00055 add_option
00056 ("transparent", "alpha", 0,
00057 "Specifies the maximum alpha value (in the range of 0 to 1) for a "
00058 "pixel to be considered fully transparent. The default is 0.",
00059 &ImageFixHiddenColor::dispatch_double, NULL, &_max_transparent_alpha);
00060
00061 _min_opaque_alpha = 1.0;
00062 _max_transparent_alpha = 0.0;
00063 }
00064
00065
00066
00067
00068
00069
00070 void ImageFixHiddenColor::
00071 run() {
00072 PNMImage alpha_image;
00073
00074 if (_alpha_filename.empty()) {
00075
00076
00077 if (!_image.has_alpha()) {
00078 nout << "Image does not have an alpha channel.\n";
00079 exit(1);
00080 }
00081 alpha_image = _image;
00082
00083 } else {
00084
00085 if (!alpha_image.read(_alpha_filename)) {
00086 nout << "Unable to read " << _alpha_filename << ".\n";
00087 exit(1);
00088 }
00089
00090 if (!alpha_image.has_alpha()) {
00091
00092
00093 alpha_image.add_alpha();
00094 int xi, yi;
00095 for (yi = 0; yi < alpha_image.get_y_size(); ++yi) {
00096 for (xi = 0; xi < alpha_image.get_x_size(); ++xi) {
00097 alpha_image.set_alpha(xi, yi, alpha_image.get_gray(xi, yi));
00098 }
00099 }
00100 }
00101
00102
00103 if (alpha_image.get_x_size() != _image.get_x_size() ||
00104 alpha_image.get_y_size() != _image.get_y_size()) {
00105 PNMImage scaled(_image.get_x_size(), _image.get_y_size(), alpha_image.get_num_channels());
00106 scaled.quick_filter_from(alpha_image);
00107 alpha_image = scaled;
00108 }
00109 }
00110
00111
00112 int count = 0;
00113 LRGBColord color(0.0, 0.0, 0.0);
00114 int xi, yi;
00115 for (yi = 0; yi < _image.get_y_size(); ++yi) {
00116 for (xi = 0; xi < _image.get_x_size(); ++xi) {
00117 if (alpha_image.get_alpha(xi, yi) >= _min_opaque_alpha) {
00118 color += _image.get_xel(xi, yi);
00119 ++count;
00120 }
00121 }
00122 }
00123 if (count == 0) {
00124 nout << "Image has no opaque pixels.\n";
00125 exit(1);
00126 }
00127 color /= (double)count;
00128 nout << " average color of " << count << " opaque pixels is " << color << "\n";
00129
00130
00131 count = 0;
00132 for (yi = 0; yi < _image.get_y_size(); ++yi) {
00133 for (xi = 0; xi < _image.get_x_size(); ++xi) {
00134 if (alpha_image.get_alpha(xi, yi) <= _max_transparent_alpha) {
00135 _image.set_xel(xi, yi, color);
00136 ++count;
00137 }
00138 }
00139 }
00140 if (count == 0) {
00141 nout << "Image has no transparent pixels.\n";
00142 exit(1);
00143 }
00144 nout << " applied to " << count << " transparent pixels.\n";
00145
00146 write_image(_image);
00147 }
00148
00149
00150 int main(int argc, char *argv[]) {
00151
00152 pystub();
00153
00154 ImageFixHiddenColor prog;
00155 prog.parse_command_line(argc, argv);
00156 prog.run();
00157 return 0;
00158 }