home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / TEST / IMAGE_CU.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  16.2 KB  |  506 lines

  1.  
  2. package sub_arctic.test;
  3.  
  4. import sub_arctic.lib.*;
  5. import sub_arctic.output.*;
  6. import sub_arctic.input.*;
  7. import sub_arctic.constraints.std_function;
  8.  
  9. import java.util.Vector;
  10. import java.net.URL;
  11. import java.net.MalformedURLException;
  12. import java.io.FileOutputStream;
  13. import java.io.PrintStream;
  14. import java.io.IOException;
  15. import java.awt.Font;
  16. import java.awt.Color;
  17. import java.awt.image.ImageObserver;
  18. import java.awt.image.PixelGrabber;
  19.  
  20. /** 
  21.  * This is a small demo program that allows rectangular sections to be 
  22.  * cut out of images (loaded from a URL) and then written out as subArctic
  23.  * code for statically initializing a loaded_image object.
  24.  *
  25.  * @author Scott Hudson
  26.  */
  27. public class image_cutter extends debug_interactor_applet 
  28.   implements callback_object, interactor_consts {
  29.  
  30.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  31.   /* Misc. constants */
  32.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  33.  
  34.   /** Border around image */
  35.   protected static final int border = 40;
  36.  
  37.   /** Cutter inset from border */
  38.   protected static final int cutter_inset = 10;
  39.  
  40.   /** Font for coord display tags */
  41.   protected static Font tag_font = new Font("Helvetica", Font.PLAIN, 9);
  42.  
  43.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  44.   /* Defaults */
  45.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  46.  
  47.   /** Default URL for the image */
  48.   protected static final String default_url = 
  49.     "http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic_logo.gif";
  50.  
  51.   /** Default save name */
  52.   protected static final String default_save = "image.code";
  53.  
  54.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  55.   /* Parts of the interface that need to be accessed by callback */
  56.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  57.  
  58.   /** Icon object holding the image we are dealing with */
  59.   protected icon the_image;
  60.  
  61.   /** Cutter interactor for x1 */
  62.   protected interactor cut_x1;
  63.  
  64.   /** Cutter interactor for y1 */
  65.   protected interactor cut_y1;
  66.  
  67.   /** Cutter interactor for x2 */
  68.   protected interactor cut_x2;
  69.  
  70.   /** Cutter interactor for y2 */
  71.   protected interactor cut_y2;
  72.  
  73.   /** Text edit area for URL to load from */
  74.   protected oneline_text_edit load_name;
  75.  
  76.   /** Text edit area for file to save to */
  77.   protected oneline_text_edit save_name;
  78.  
  79.   /** Button for loading */
  80.   protected button load_button;
  81.  
  82.   /** Button for saving */
  83.   protected button save_button;
  84.  
  85.   /** Label for error message */
  86.   protected label message;
  87.  
  88.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  89.   /* Methods */
  90.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  91.  
  92.   /**
  93.    * Initialization of sub_arctic interface when applet starts 
  94.    * @param base_parent_interactor top the root interactor we build under
  95.    */
  96.   public void build_ui(base_parent_interactor top) 
  97.     {
  98.       column                 whole_ui;
  99.       base_parent_interactor image_holder;
  100.       row                    a_row;
  101.       label                  tag;
  102.  
  103.       /* build a column to put everything in */
  104.       whole_ui = new column(10,10, false, false, column.CENTER_JUSTIFIED);
  105.       top.add_child(whole_ui);
  106.  
  107.       /* put in row with label, text box, and load button */
  108.       a_row = new row(0,5, false, false, row.CENTER_JUSTIFIED);
  109.       whole_ui.add_child(a_row);
  110.       tag = new label("Image URL:");
  111.       a_row.add_child(tag);
  112.       load_name = new oneline_text_edit(0,0, 400, default_url, null, false);
  113.       a_row.add_child(load_name);
  114.       load_button = new button("Load", this);
  115.       a_row.add_child(load_button);
  116.  
  117.       /* Create image holder parent constrained by size of the image */
  118.       image_holder = new base_parent_interactor();
  119.       image_holder.set_w_constraint(
  120.     std_function.offset(FIRST_CHILD.W(), 2*border));
  121.       image_holder.set_h_constraint(
  122.     std_function.offset(FIRST_CHILD.H(), 2*border));
  123.       whole_ui.add_child(image_holder);
  124.  
  125.       /* Place default image in the holder */
  126.       the_image = new icon(border,border, new loaded_image(16,16));
  127.       load_image(default_url);
  128.       image_holder.add_child(the_image);
  129.  
  130.       /* build cutter lines */
  131.       cut_x1 = build_vert_cutter(true);
  132.       cut_x2 = build_vert_cutter(false);
  133.       cut_y1 = build_horiz_cutter(true);
  134.       cut_y2 = build_horiz_cutter(false);
  135.  
  136.       /* add them to the parent along */
  137.       image_holder.add_child(cut_x2);
  138.       image_holder.add_child(cut_x1);
  139.       image_holder.add_child(cut_y2);
  140.       image_holder.add_child(cut_y1);
  141.  
  142.       /* add a size display */
  143.       whole_ui.add_child(build_size_display());
  144.  
  145.       /* put in row with label, text box, and save button */
  146.       a_row = new row(0,5, false, false, row.CENTER_JUSTIFIED);
  147.       whole_ui.add_child(a_row);
  148.       tag  = new label("Save As:");
  149.       a_row.add_child(tag);
  150.       save_name = new oneline_text_edit(0,0, 400, default_save, null, false);
  151.       a_row.add_child(save_name);
  152.       save_button = new button("Save", this);
  153.       a_row.add_child(save_button);
  154.  
  155.       /* finally put an error message label at the bottom */
  156.       message = new label("");
  157.       whole_ui.add_child(message);
  158.     }
  159.  
  160.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  161.  
  162.   /**
  163.    * Build a horizontal cutter line and tag inside a drag container
  164.    * @param boolean near_line indication of near or far line.
  165.    */
  166.   protected interactor build_horiz_cutter(boolean near_line)
  167.     {
  168.       hv_line        the_line;
  169.       int_label      the_tag;
  170.       drag_container drag = null;
  171.       int            xloc, yloc;
  172.  
  173.       /* build a drag container to put this in */
  174.       xloc = cutter_inset;
  175.       yloc = near_line ? border : border + the_image.h()-1;
  176.       drag = new vert_drag_container(xloc, yloc, false, this);
  177.  
  178.       /* create the line with length constrained to the image */
  179.       the_line = new hv_line(true);
  180.       the_line.set_w_constraint(
  181.     std_function.offset(OTHER.OBJ(the_image).W(),2*(border-cutter_inset)-1));
  182.  
  183.       /* put the line in the drag container */
  184.       drag.add_child(the_line);
  185.  
  186.       /* Build a coordinate display tag with display value tied to drag 
  187.        * position.  Note: we use PART(Y) instead of Y() here so we get the 
  188.        * value in the coordinate system of the drag's parent's. Otherwise it 
  189.        * would be in our parents coordinates (i.e., drag's coordinates) and 
  190.        * always 0.
  191.        */
  192.       the_tag = new int_label(0, tag_font);
  193.       the_tag.set_opaque(true);
  194.       the_tag.set_boxed(true);
  195.       the_tag.set_part_a_constraint(std_function.offset(OTHER.OBJ(drag).PART(Y),
  196.                                     -border));
  197.  
  198.       /* for far lines, constrain the tag to stay at end of the line, 
  199.        * otherwise it stays at 0,0.
  200.        */
  201.       if (!near_line)
  202.       {
  203.     the_tag.set_x_constraint(std_function.far_edge_just(PREV_SIBLING.W(),0));
  204.       }
  205.  
  206.       /* put the tag in the drag container also, and we are done */
  207.       drag.add_child(the_tag);
  208.  
  209.       return drag;
  210.     }
  211.  
  212.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  213.  
  214.   /**
  215.    * Build a vertical cutter line and tag inside a drag container
  216.    * @param boolean near_line indication of near or far line.
  217.    */
  218.   protected interactor build_vert_cutter(boolean near_line)
  219.     {
  220.       hv_line        the_line;
  221.       int_label      the_tag;
  222.       drag_container drag = null;
  223.       int            xloc, yloc;
  224.  
  225.       /* build a drag container to put this in */
  226.       xloc = near_line ? border : border+the_image.w()-1;
  227.       yloc = cutter_inset;
  228.       drag = new horiz_drag_container(xloc, yloc, false, this);
  229.  
  230.       /* create the line with length constrained to the image */
  231.       the_line = new hv_line(false);
  232.       the_line.set_h_constraint(
  233.     std_function.offset(OTHER.OBJ(the_image).H(),2*(border-cutter_inset)-1));
  234.  
  235.       /* put the line in the drag container */
  236.       drag.add_child(the_line);
  237.  
  238.       /* Build a coordinate display tag with display value tied to drag 
  239.        * position.  Note: we use PART(X) instead of X() here so we get the 
  240.        * value in the coordinate system of the drag's parent's. Otherwise it 
  241.        * would be in our parents coordinates (i.e., drag's coordinates) and 
  242.        * always 0.
  243.        */
  244.       the_tag = new int_label(0, tag_font);
  245.       the_tag.set_opaque(true);
  246.       the_tag.set_boxed(true);
  247.       the_tag.set_part_a_constraint(std_function.offset(OTHER.OBJ(drag).PART(X),
  248.                                     -border));
  249.  
  250.       /* for far lines, constrain the tag to stay at end of the line, 
  251.        * otherwise it stays at 0,0.
  252.        */
  253.       if (!near_line)
  254.       {
  255.     the_tag.set_y_constraint(std_function.far_edge_just(PREV_SIBLING.H(),0)); 
  256.       }
  257.  
  258.       /* put the tag in the drag container also, and we are done */
  259.       drag.add_child(the_tag);
  260.  
  261.       return drag;
  262.     }
  263.  
  264.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  265.   
  266.   /**
  267.    * Build objects for a size display
  268.    */
  269.   protected interactor build_size_display()
  270.     {
  271.       row   result = null;
  272.       label tag;
  273.  
  274.       /* build a row to put it in */
  275.       result = new row(0,0, false, false, row.CENTER_JUSTIFIED);
  276.  
  277.       /* build leading label */
  278.       tag = new label("Image size: "); tag.set_opaque(true);
  279.       result.add_child(tag);
  280.   
  281.       /* build int_label constrained to x size */
  282.       tag = new int_label(0); tag.set_opaque(true);
  283.       tag.set_part_a_constraint(
  284.     std_function.subtract(OTHER.OBJ(cut_x2).X(), OTHER.OBJ(cut_x1).X(), 1));
  285.       result.add_child(tag);
  286.  
  287.       /* add separator label */
  288.       tag = new label("x"); tag.set_opaque(true);
  289.       result.add_child(tag);
  290.  
  291.       /* build int_label constrained to x size */
  292.       tag = new int_label(0); tag.set_opaque(true);
  293.       tag.set_part_a_constraint(
  294.     std_function.subtract(OTHER.OBJ(cut_y2).Y(), OTHER.OBJ(cut_y1).Y(), 1));
  295.       result.add_child(tag);
  296.  
  297.       return result;
  298.     }
  299.  
  300.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  301.  
  302.   /** 
  303.    * Handle callbacks. 
  304.    */
  305.   public void callback(interactor from, event evt, int cb_num, Object cb_parm)
  306.     {
  307.       /* clear out any old message */
  308.       message.set_text("");
  309.  
  310.       /* is the callback a drag from one of the cutters? */
  311.       if (from instanceof drag_container)
  312.     {
  313.       /* make sure cutters are in bounds and in order */
  314.       fix_cut_bounds(from);
  315.     }
  316.  
  317.       /* is the callback from the load button */
  318.       else if (from == load_button)
  319.     {
  320.       /* load the image */
  321.       load_image(load_name.text());
  322.  
  323.       /* force cutter positions into new bounds */
  324.       fix_cut_bounds(null);
  325.     }
  326.  
  327.       /* is the callback from the save button */
  328.       else if (from == save_button)
  329.     {
  330.       save_image(save_name.text());
  331.     }
  332.  
  333.     }
  334.  
  335.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  336.  
  337.   /** Make sure cutters in in bounds and in order */
  338.   protected void fix_cut_bounds(interactor from)
  339.     {
  340.       /* force everyone to be in bounds */
  341.       if (cut_x1.x() < border) cut_x1.set_x(border);
  342.       if (cut_x2.x() < border) cut_x2.set_x(border);
  343.       if (cut_x1.x() > the_image.w()-1+border) 
  344.     cut_x1.set_x(the_image.w()-1+border);
  345.       if (cut_x2.x() > the_image.w()-1+border) 
  346.     cut_x2.set_x(the_image.w()-1+border);
  347.       if (cut_y1.y() < border) cut_y1.set_y(border);
  348.       if (cut_y2.y() < border) cut_y2.set_y(border);
  349.       if (cut_y1.y() > the_image.h()-1+border) 
  350.     cut_y1.set_y(the_image.h()-1+border);
  351.       if (cut_y2.y() > the_image.h()-1+border) 
  352.     cut_y2.set_y(the_image.h()-1+border);
  353.     
  354.       /* reorder if dragged cutter crosses its mate */
  355.       if (from == cut_x1 && cut_x1.x() > cut_x2.x())  
  356.     cut_x1.set_x(cut_x2.x());
  357.       else if (from == cut_x2 && cut_x1.x() > cut_x2.x())  
  358.     cut_x2.set_x(cut_x1.x());
  359.       else if (from == cut_y1 && cut_y1.y() > cut_y2.y())  
  360.     cut_y1.set_y(cut_y2.y());
  361.       else if (from == cut_y2 && cut_y1.y() > cut_y2.y())  
  362.     cut_y2.set_y(cut_y1.y());
  363.     }
  364.  
  365.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  366.  
  367.   /** Load image from given location (a URL) */
  368.   protected void load_image(String name)
  369.     {
  370.     /* load the image */
  371.         try {
  372.           the_image.set_image(manager.load_image(new URL(name)));
  373.         } catch(MalformedURLException ex) {
  374.           /* Couldn't load, so use the broken image icon */
  375.           the_image.set_image(std.broken_image_icon());
  376.         }
  377.     }
  378.  
  379.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  380.  
  381.   /** Write image (as subArctic static init code) into file with given name */
  382.   protected void save_image(String name)
  383.     {
  384.       String       image_name;
  385.       PrintStream  fil; 
  386.       int          size_w, size_h;
  387.       PixelGrabber grabber;
  388.       int[]        pixels;
  389.       int          i, cnt, pos;
  390.       long         pix;
  391.  
  392.       /* try to open the named file */
  393.       try {
  394.     fil = new PrintStream(new FileOutputStream(name));
  395.       } catch (IOException ex) {
  396.     message.set_text("Can't open \"" + name + "\" for output.");
  397.     return;
  398.       } catch (SecurityException ex2) {
  399.     message.set_text("Security Exception: " + 
  400.            "Sorry, can't write files under the current security settings.");
  401.     return;
  402.       }
  403.  
  404.       /* trim off leading directory components from file name */
  405.       image_name = name;
  406.       pos = image_name.lastIndexOf("/");
  407.       if (pos != -1) image_name = image_name.substring(pos+1);
  408.  
  409.       /* trim off trailing suffix from file name */
  410.       pos = image_name.lastIndexOf(".");
  411.       if (pos != -1) image_name = image_name.substring(0,pos);
  412.  
  413.       /* measure the cut */
  414.       size_w = cut_x2.x() - cut_x1.x() + 1;
  415.       size_h = cut_y2.y() - cut_y1.y() + 1;
  416.       pixels = new int[size_w*size_h];
  417.  
  418.       /* pull out the pixels being reguested */
  419.       grabber = new PixelGrabber(the_image.image().image(), 
  420.     cut_x1.x(), cut_y1.y(),  size_w, size_h, pixels, 0, size_w);
  421.       try {
  422.     grabber.grabPixels();
  423.       } catch (InterruptedException ex) {
  424.     message.set_text("Pixel cut failed do to \"Interrupted Exception\"");
  425.     return;
  426.       }
  427.  
  428.       /* check that it really worked. */
  429.       if ((grabber.status() & ImageObserver.ABORT) != 0)
  430.     {
  431.       message.set_text("Error or abort in grabbing pixels");
  432.       return;
  433.     }
  434.  
  435.       /* write out first part of code */
  436.       fil.println("  // (generated from image_cutter)");
  437.       fil.println("  protected static int "+image_name+"_width = " +size_w+";");
  438.       fil.println("  protected static int "+image_name+"_height = "+size_h+";");
  439.       fil.println("  protected static int[] "+ image_name+"_data = {");
  440.  
  441.       /* indent */
  442.       fil.print("    ");
  443.  
  444.       /* write out each pixel */
  445.       cnt = 0;
  446.       for (i = 0; i < size_w*size_h; i++)
  447.     {
  448.       /* write pixel in unsigned hex */
  449.       pix = pixels[i];
  450.       pix &= 0xffffffffL;
  451.       fil.print("0x" + Long.toString(pix, 16));
  452.       if (i != size_w*size_h-1)
  453.         {
  454.           fil.print(",");
  455.         }
  456.  
  457.       /* break the line after 6th value */
  458.       cnt++;
  459.       if (cnt == 6)
  460.         {
  461.           /* end line and indent */
  462.           fil.println();
  463.               fil.print("    ");
  464.           cnt = 0;
  465.         }
  466.     }
  467.  
  468.       /* do the rest of the code */
  469.       fil.println("};");
  470.       fil.println("  protected static sub_arctic.output.loaded_image _" +
  471.                 image_name + " = null;");
  472.       fil.println();
  473.       fil.println("  public static sub_arctic.output.loaded_image " + 
  474.                image_name + "() {");
  475.       fil.println("    if (_" + image_name + " == null)");
  476.       fil.println("      _"+image_name+" = new sub_arctic.output.loaded_image("
  477.                    +image_name+"_data,");
  478.       fil.println("           "+image_name+"_width,"+image_name+"_height);");
  479.       fil.println("    return _"+image_name+";");
  480.       fil.println("  }");
  481.  
  482.       message.set_text(size_w + "x" + size_h + " image written to \"" + 
  483.                 name + "\".");
  484.     }
  485.  
  486.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  487.  
  488. }
  489.  
  490. /*=========================== COPYRIGHT NOTICE ===========================
  491.  
  492. This file is part of the subArctic user interface toolkit.
  493.  
  494. Copyright (c) 1996 Scott Hudson and Ian Smith
  495. All rights reserved.
  496.  
  497. The subArctic system is freely available for most uses under the terms
  498. and conditions described in 
  499.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  500. and appearing in full in the lib/interactor.java source file.
  501.  
  502. The current release and additional information about this software can be 
  503. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  504.  
  505. ========================================================================*/
  506.