Ver código fonte

add PNMImage::threshold()

David Rose 16 anos atrás
pai
commit
849dc8cccb
2 arquivos alterados com 98 adições e 0 exclusões
  1. 94 0
      panda/src/pnmimage/pnmImage.cxx
  2. 4 0
      panda/src/pnmimage/pnmImage.h

+ 94 - 0
panda/src/pnmimage/pnmImage.cxx

@@ -939,6 +939,100 @@ lighten_sub_image(const PNMImage &copy, int xto, int yto,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PNMImage::threshold
+//       Access: Published
+//  Description: Selectively copies each pixel from either one source
+//               or another source, depending on the alpha channel of
+//               alpha_image.
+//
+//               For each pixel (x, y), assigns the corresponding
+//               pixel (x, y) in this image to:
+//
+//               lt.get_xel(x, y) if alpha_image(x, y).get_alpha() <=
+//               threshold, or
+//
+//               ge.get_xel(x, y) if alpha_image(x, y).get_alpha() >
+//               threshold
+//
+//               Any of alpha_image, lt, or ge may be the same PNMImge
+//               object as this image, or the same as each other; or
+//               they may all be different.
+//
+//               All images must be the same size.
+////////////////////////////////////////////////////////////////////
+void PNMImage::
+threshold(const PNMImage &alpha_image,
+          const PNMImage &lt, const PNMImage &ge,
+          double threshold) {
+  nassertv(get_x_size() <= alpha_image.get_x_size() && get_y_size() <= alpha_image.get_y_size());
+  nassertv(get_x_size() <= lt.get_x_size() && get_y_size() <= lt.get_y_size());
+  nassertv(get_x_size() <= ge.get_x_size() && get_y_size() <= ge.get_y_size());
+  nassertv(alpha_image.has_alpha());
+
+  xelval threshold_val = (xelval)(alpha_image.get_maxval() * threshold + 0.5);
+
+  if (get_maxval() == lt.get_maxval() && get_maxval() == ge.get_maxval()) {
+    // Simple case: the maxvals are all equal.  Copy by integer value.
+    int x, y;
+
+    if (has_alpha() && lt.has_alpha() && ge.has_alpha()) {
+      // Copy alpha channel too.
+      for (y = 0; y < get_y_size(); y++) {
+        for (x = 0; x < get_x_size(); x++) {
+          if (alpha_image.get_alpha_val(x, y) < threshold_val) {
+            set_xel_val(x, y, lt.get_xel_val(x, y));
+            set_alpha_val(x, y, lt.get_alpha_val(x, y));
+          } else {
+            set_xel_val(x, y, ge.get_xel_val(x, y));
+            set_alpha_val(x, y, ge.get_alpha_val(x, y));
+          }
+        }
+      }
+
+    } else {
+      // Don't copy alpha channel.
+      for (y = 0; y < get_y_size(); y++) {
+        for (x = 0; x < get_x_size(); x++) {
+          if (alpha_image.get_alpha_val(x, y) < threshold_val) {
+            set_xel_val(x, y, lt.get_xel_val(x, y));
+          } else {
+            set_xel_val(x, y, ge.get_xel_val(x, y));
+          }
+        }
+      }
+    }
+
+  } else {
+    // General case: the maxvals are different.  Copy by floating-point value.
+    int x, y;
+
+    if (has_alpha() && lt.has_alpha() && ge.has_alpha()) {
+      for (y = 0; y < get_y_size(); y++) {
+        for (x = 0; x < get_x_size(); x++) {
+          if (alpha_image.get_alpha_val(x, y) < threshold_val) {
+            set_xel(x, y, lt.get_xel(x, y));
+            set_alpha(x, y, lt.get_alpha(x, y));
+          } else {
+            set_xel(x, y, ge.get_xel(x, y));
+            set_alpha(x, y, ge.get_alpha(x, y));
+          }
+        }
+      }
+    } else {
+      for (y = 0; y < get_y_size(); y++) {
+        for (x = 0; x < get_x_size(); x++) {
+          if (alpha_image.get_alpha_val(x, y) < threshold_val) {
+            set_xel(x, y, lt.get_xel(x, y));
+          } else {
+            set_xel(x, y, ge.get_xel(x, y));
+          }
+        }
+      }
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PNMImage::copy_channel
 //       Access: Published

+ 4 - 0
panda/src/pnmimage/pnmImage.h

@@ -206,6 +206,10 @@ PUBLISHED:
                          int xfrom = 0, int yfrom = 0,
                          int x_size = -1, int y_size = -1,
                          double pixel_scale = 1.0);
+  void threshold(const PNMImage &alpha_image,
+                 const PNMImage &lt, const PNMImage &ge,
+                 double threshold);
+  
   void copy_channel(const PNMImage &copy, int xto, int yto, int cto,
                     int xfrom = 0, int yfrom = 0, int cfrom = 0,
                     int x_size = -1, int y_size = -1);