浏览代码

*** empty log message ***

David Rose 17 年之前
父节点
当前提交
53c77b0565

+ 6 - 0
pandatool/src/imageprogs/Sources.pp

@@ -20,6 +20,12 @@
     imageResize.cxx imageResize.h imageResize.I
     imageResize.cxx imageResize.h imageResize.I
 #end bin_target
 #end bin_target
 
 
+#begin bin_target
+  #define TARGET image-fix-hidden-color
+  #define SOURCES \
+    imageFixHiddenColor.cxx imageFixHiddenColor.h imageFixHiddenColor.I
+#end bin_target
+
 #begin bin_target
 #begin bin_target
   #define TARGET image-info
   #define TARGET image-info
   #define SOURCES \
   #define SOURCES \

+ 14 - 0
pandatool/src/imageprogs/imageFixHiddenColor.I

@@ -0,0 +1,14 @@
+// Filename: imageFixHiddenColor.I
+// Created by:  drose (13Mar03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+

+ 158 - 0
pandatool/src/imageprogs/imageFixHiddenColor.cxx

@@ -0,0 +1,158 @@
+// Filename: imageFixHiddenColor.cxx
+// Created by:  drose (13Mar03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "imageFixHiddenColor.h"
+#include "string_utils.h"
+#include "pystub.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: ImageFixHiddenColor::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+ImageFixHiddenColor::
+ImageFixHiddenColor() : ImageFilter(true) {
+  set_program_description
+    ("This program is designed to fix the color channels of an "
+     "alpha-cutout image, making the \"color\" of the invisible part of the "
+     "image consistent with the rest of the image.  It does this by "
+     "analyzing the RGB values of the image where alpha == 1, and using the "
+     "average of these values as the overall image color, which it then "
+     "applies to the image wherever alpha == 0.  When the alpha value is "
+     "neither 1 nor 0, the pixel is ignored.\n\n"
+
+     "This process is important for applications that filter the texture "
+     "size down by averaging neighboring pixels.  If the color under the "
+     "alpha == 0 pixels is very different from the color elsewhere, this "
+     "kind of filtering can have a visible effect on the image's color, even "
+     "where alpha != 0.");
+
+  add_option
+    ("alpha", "filename", 0,
+     "Specifies a separate filename that will be used in lieu of the "
+     "alpha channel on the source image.  If this file has an alpha "
+     "channel, that alpha channel is used; otherwise, the grayscale "
+     "value of the image is used.",
+     &ImageFixHiddenColor::dispatch_filename, NULL, &_alpha_filename);
+
+  add_option
+    ("opaque", "alpha", 0,
+     "Specifies the minimum alpha value (in the range of 0 to 1) for a "
+     "pixel to be considered fully opaque.  The default is 1.",
+     &ImageFixHiddenColor::dispatch_double, NULL, &_min_opaque_alpha);
+
+  add_option
+    ("transparent", "alpha", 0,
+     "Specifies the maximum alpha value (in the range of 0 to 1) for a "
+     "pixel to be considered fully transparent.  The default is 0.",
+     &ImageFixHiddenColor::dispatch_double, NULL, &_max_transparent_alpha);
+
+  _min_opaque_alpha = 1.0;
+  _max_transparent_alpha = 0.0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ImageFixHiddenColor::run
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void ImageFixHiddenColor::
+run() {
+  PNMImage alpha_image;
+
+  if (_alpha_filename.empty()) {
+    // No separate alpha file is provided; use the base file's alpha
+    // channel.
+    if (!_image.has_alpha()) {
+      nout << "Image does not have an alpha channel.\n";
+      exit(1);
+    }
+    alpha_image = _image;
+
+  } else {
+    // In this case, the alpha channel is in a separate file.
+    if (!alpha_image.read(_alpha_filename)) {
+      nout << "Unable to read " << _alpha_filename << ".\n";
+      exit(1);
+    }
+
+    if (!alpha_image.has_alpha()) {
+      // Copy the grayscale value to the alpha channel for the benefit
+      // of the code below.
+      alpha_image.add_alpha();
+      int xi, yi;
+      for (yi = 0; yi < alpha_image.get_y_size(); ++yi) {
+        for (xi = 0; xi < alpha_image.get_x_size(); ++xi) {
+          alpha_image.set_alpha(xi, yi, alpha_image.get_gray(xi, yi));
+        }
+      }
+    }
+
+    // Make sure the alpha image matches the size of the source image.
+    if (alpha_image.get_x_size() != _image.get_x_size() ||
+        alpha_image.get_y_size() != _image.get_y_size()) {
+      PNMImage scaled(_image.get_x_size(), _image.get_y_size(), alpha_image.get_num_channels());
+      scaled.quick_filter_from(alpha_image);
+      alpha_image = scaled;
+    }
+  }
+
+  // First, get the average color of all the opaque pixels.
+  int count = 0;
+  RGBColord color(0.0, 0.0, 0.0);
+  int xi, yi;
+  for (yi = 0; yi < _image.get_y_size(); ++yi) {
+    for (xi = 0; xi < _image.get_x_size(); ++xi) {
+      if (alpha_image.get_alpha(xi, yi) >= _min_opaque_alpha) {
+        color += _image.get_xel(xi, yi);
+        ++count;
+      }
+    }
+  }
+  if (count == 0) {
+    nout << "Image has no opaque pixels.\n";
+    exit(1);
+  }
+  color /= (double)count;
+  nout << "  average color of " << count << " opaque pixels is " << color << "\n";
+  
+  // Now, apply that wherever there are transparent pixels.
+  count = 0;
+  for (yi = 0; yi < _image.get_y_size(); ++yi) {
+    for (xi = 0; xi < _image.get_x_size(); ++xi) {
+      if (alpha_image.get_alpha(xi, yi) <= _max_transparent_alpha) {
+        _image.set_xel(xi, yi, color);
+        ++count;
+      }
+    }
+  }
+  if (count == 0) {
+    nout << "Image has no transparent pixels.\n";
+    exit(1);
+  }
+  nout << "  applied to " << count << " transparent pixels.\n";
+    
+  write_image(_image);
+}
+
+
+int main(int argc, char *argv[]) {
+  // A call to pystub() to force libpystub.so to be linked in.
+  pystub();
+
+  ImageFixHiddenColor prog;
+  prog.parse_command_line(argc, argv);
+  prog.run();
+  return 0;
+}

+ 42 - 0
pandatool/src/imageprogs/imageFixHiddenColor.h

@@ -0,0 +1,42 @@
+// Filename: imageFixHiddenColor.h
+// Created by:  drose (13Mar03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef IMAGEFIXHIDDENCOLOR_H
+#define IMAGEFIXHIDDENCOLOR_H
+
+#include "pandatoolbase.h"
+
+#include "imageFilter.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ImageFixHiddenColor
+// Description : This program repairs an image's RGB values hidden
+//               behind an A value of 0.
+////////////////////////////////////////////////////////////////////
+class ImageFixHiddenColor : public ImageFilter {
+public:
+  ImageFixHiddenColor();
+
+  void run();
+
+private:
+  Filename _alpha_filename;
+  double _min_opaque_alpha;
+  double _max_transparent_alpha;
+};
+
+#include "imageFixHiddenColor.I"
+
+#endif
+