예제 #1
0
      /* ClosestColor traverses the color cube tree at a
       * particular node and determines which colormap entry
       * best represents the input color.
       */
      void closestColor(int red, int green, int blue, Search search) {
        if (nchild != 0) {
          for (int id = 0; id < 8; id++) {
            if (child[id] != null) {
              child[id].closestColor(red, green, blue, search);
            }
          }
        }

        if (unique != 0) {
          int color = cube.colormap[color_number];
          int distance = distance(color, red, green, blue);
          if (distance < search.distance) {
            search.distance = distance;
            search.color_number = color_number;
          }
        }
      }
예제 #2
0
    /*
     * Procedure assignment generates the output image from the
     * pruned tree. The output image consists of two parts: (1) A
     * color map, which is an array of color descriptions (RGB
     * triples) for each color present in the output image; (2) A
     * pixel array, which represents each pixel as an index into
     * the color map array.
     *
     * First, the assignment phase makes one pass over the pruned
     * color description tree to establish the image's color map.
     * For each node with n2 > 0, it divides Sr, Sg, and Sb by n2.
     * This produces the mean color of all pixels that classify no
     * lower than this node. Each of these colors becomes an entry
     * in the color map.
     *
     * Finally, the assignment phase reclassifies each pixel in
     * the pruned tree to identify the deepest node containing the
     * pixel's color. The pixel's value in the pixel array becomes
     * the index of this node's mean color in the color map.
     */
    void assignment() {
      colormap = new int[colors];
      colors = 0;
      root.colormap();

      int pixels[][] = this.pixels;

      int width = pixels.length;
      int height = pixels[0].length;

      Search search = new Search();

      int transPad = hasTrans ? 1 : 0;

      // convert to indexed color
      for (int x = width; x-- > 0; ) {
        for (int y = height; y-- > 0; ) {
          int pixel = pixels[x][y];
          int alpha = (pixel >> 24) & 0xFF;
          if (alpha != 255) {
            pixels[x][y] = 0; // transparent
            continue;
          }
          int red = (pixel >> 16) & 0xFF;
          int green = (pixel >> 8) & 0xFF;
          int blue = (pixel >> 0) & 0xFF;

          // walk the tree to find the cube containing that color
          Node node = root;
          for (; ; ) {
            int id =
                (((red > node.mid_red ? 1 : 0) << 0)
                    | ((green > node.mid_green ? 1 : 0) << 1)
                    | ((blue > node.mid_blue ? 1 : 0) << 2));
            if (node.child[id] == null) {
              break;
            }
            node = node.child[id];
          }

          if (QUICK) {
            // if QUICK is set, just use that
            // node. Strictly speaking, this isn't
            // necessarily best match.
            pixels[x][y] = node.color_number + transPad;
          } else {
            // Find the closest color.
            search.distance = Integer.MAX_VALUE;
            node.parent.closestColor(red, green, blue, search);
            pixels[x][y] = search.color_number + transPad;
          }
        }
      }

      // expand the colormap by one to account for the transparent
      if (hasTrans) {
        int[] newcmap = new int[colormap.length + 1];
        System.arraycopy(colormap, 0, newcmap, 1, colormap.length);
        colormap = newcmap;
      }
    }