home *** CD-ROM | disk | FTP | other *** search
-
- package sub_arctic.test;
-
- import sub_arctic.lib.*;
- import sub_arctic.output.*;
- import sub_arctic.input.*;
- import sub_arctic.constraints.std_function;
-
- import java.util.Vector;
- import java.net.URL;
- import java.net.MalformedURLException;
- import java.io.FileOutputStream;
- import java.io.PrintStream;
- import java.io.IOException;
- import java.awt.Font;
- import java.awt.Color;
- import java.awt.image.ImageObserver;
- import java.awt.image.PixelGrabber;
-
- /**
- * This is a small demo program that allows rectangular sections to be
- * cut out of images (loaded from a URL) and then written out as subArctic
- * code for statically initializing a loaded_image object.
- *
- * @author Scott Hudson
- */
- public class image_cutter extends debug_interactor_applet
- implements callback_object, interactor_consts {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- /* Misc. constants */
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Border around image */
- protected static final int border = 40;
-
- /** Cutter inset from border */
- protected static final int cutter_inset = 10;
-
- /** Font for coord display tags */
- protected static Font tag_font = new Font("Helvetica", Font.PLAIN, 9);
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- /* Defaults */
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Default URL for the image */
- protected static final String default_url =
- "http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic_logo.gif";
-
- /** Default save name */
- protected static final String default_save = "image.code";
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- /* Parts of the interface that need to be accessed by callback */
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Icon object holding the image we are dealing with */
- protected icon the_image;
-
- /** Cutter interactor for x1 */
- protected interactor cut_x1;
-
- /** Cutter interactor for y1 */
- protected interactor cut_y1;
-
- /** Cutter interactor for x2 */
- protected interactor cut_x2;
-
- /** Cutter interactor for y2 */
- protected interactor cut_y2;
-
- /** Text edit area for URL to load from */
- protected oneline_text_edit load_name;
-
- /** Text edit area for file to save to */
- protected oneline_text_edit save_name;
-
- /** Button for loading */
- protected button load_button;
-
- /** Button for saving */
- protected button save_button;
-
- /** Label for error message */
- protected label message;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- /* Methods */
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Initialization of sub_arctic interface when applet starts
- * @param base_parent_interactor top the root interactor we build under
- */
- public void build_ui(base_parent_interactor top)
- {
- column whole_ui;
- base_parent_interactor image_holder;
- row a_row;
- label tag;
-
- /* build a column to put everything in */
- whole_ui = new column(10,10, false, false, column.CENTER_JUSTIFIED);
- top.add_child(whole_ui);
-
- /* put in row with label, text box, and load button */
- a_row = new row(0,5, false, false, row.CENTER_JUSTIFIED);
- whole_ui.add_child(a_row);
- tag = new label("Image URL:");
- a_row.add_child(tag);
- load_name = new oneline_text_edit(0,0, 400, default_url, null, false);
- a_row.add_child(load_name);
- load_button = new button("Load", this);
- a_row.add_child(load_button);
-
- /* Create image holder parent constrained by size of the image */
- image_holder = new base_parent_interactor();
- image_holder.set_w_constraint(
- std_function.offset(FIRST_CHILD.W(), 2*border));
- image_holder.set_h_constraint(
- std_function.offset(FIRST_CHILD.H(), 2*border));
- whole_ui.add_child(image_holder);
-
- /* Place default image in the holder */
- the_image = new icon(border,border, new loaded_image(16,16));
- load_image(default_url);
- image_holder.add_child(the_image);
-
- /* build cutter lines */
- cut_x1 = build_vert_cutter(true);
- cut_x2 = build_vert_cutter(false);
- cut_y1 = build_horiz_cutter(true);
- cut_y2 = build_horiz_cutter(false);
-
- /* add them to the parent along */
- image_holder.add_child(cut_x2);
- image_holder.add_child(cut_x1);
- image_holder.add_child(cut_y2);
- image_holder.add_child(cut_y1);
-
- /* add a size display */
- whole_ui.add_child(build_size_display());
-
- /* put in row with label, text box, and save button */
- a_row = new row(0,5, false, false, row.CENTER_JUSTIFIED);
- whole_ui.add_child(a_row);
- tag = new label("Save As:");
- a_row.add_child(tag);
- save_name = new oneline_text_edit(0,0, 400, default_save, null, false);
- a_row.add_child(save_name);
- save_button = new button("Save", this);
- a_row.add_child(save_button);
-
- /* finally put an error message label at the bottom */
- message = new label("");
- whole_ui.add_child(message);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Build a horizontal cutter line and tag inside a drag container
- * @param boolean near_line indication of near or far line.
- */
- protected interactor build_horiz_cutter(boolean near_line)
- {
- hv_line the_line;
- int_label the_tag;
- drag_container drag = null;
- int xloc, yloc;
-
- /* build a drag container to put this in */
- xloc = cutter_inset;
- yloc = near_line ? border : border + the_image.h()-1;
- drag = new vert_drag_container(xloc, yloc, false, this);
-
- /* create the line with length constrained to the image */
- the_line = new hv_line(true);
- the_line.set_w_constraint(
- std_function.offset(OTHER.OBJ(the_image).W(),2*(border-cutter_inset)-1));
-
- /* put the line in the drag container */
- drag.add_child(the_line);
-
- /* Build a coordinate display tag with display value tied to drag
- * position. Note: we use PART(Y) instead of Y() here so we get the
- * value in the coordinate system of the drag's parent's. Otherwise it
- * would be in our parents coordinates (i.e., drag's coordinates) and
- * always 0.
- */
- the_tag = new int_label(0, tag_font);
- the_tag.set_opaque(true);
- the_tag.set_boxed(true);
- the_tag.set_part_a_constraint(std_function.offset(OTHER.OBJ(drag).PART(Y),
- -border));
-
- /* for far lines, constrain the tag to stay at end of the line,
- * otherwise it stays at 0,0.
- */
- if (!near_line)
- {
- the_tag.set_x_constraint(std_function.far_edge_just(PREV_SIBLING.W(),0));
- }
-
- /* put the tag in the drag container also, and we are done */
- drag.add_child(the_tag);
-
- return drag;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Build a vertical cutter line and tag inside a drag container
- * @param boolean near_line indication of near or far line.
- */
- protected interactor build_vert_cutter(boolean near_line)
- {
- hv_line the_line;
- int_label the_tag;
- drag_container drag = null;
- int xloc, yloc;
-
- /* build a drag container to put this in */
- xloc = near_line ? border : border+the_image.w()-1;
- yloc = cutter_inset;
- drag = new horiz_drag_container(xloc, yloc, false, this);
-
- /* create the line with length constrained to the image */
- the_line = new hv_line(false);
- the_line.set_h_constraint(
- std_function.offset(OTHER.OBJ(the_image).H(),2*(border-cutter_inset)-1));
-
- /* put the line in the drag container */
- drag.add_child(the_line);
-
- /* Build a coordinate display tag with display value tied to drag
- * position. Note: we use PART(X) instead of X() here so we get the
- * value in the coordinate system of the drag's parent's. Otherwise it
- * would be in our parents coordinates (i.e., drag's coordinates) and
- * always 0.
- */
- the_tag = new int_label(0, tag_font);
- the_tag.set_opaque(true);
- the_tag.set_boxed(true);
- the_tag.set_part_a_constraint(std_function.offset(OTHER.OBJ(drag).PART(X),
- -border));
-
- /* for far lines, constrain the tag to stay at end of the line,
- * otherwise it stays at 0,0.
- */
- if (!near_line)
- {
- the_tag.set_y_constraint(std_function.far_edge_just(PREV_SIBLING.H(),0));
- }
-
- /* put the tag in the drag container also, and we are done */
- drag.add_child(the_tag);
-
- return drag;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Build objects for a size display
- */
- protected interactor build_size_display()
- {
- row result = null;
- label tag;
-
- /* build a row to put it in */
- result = new row(0,0, false, false, row.CENTER_JUSTIFIED);
-
- /* build leading label */
- tag = new label("Image size: "); tag.set_opaque(true);
- result.add_child(tag);
-
- /* build int_label constrained to x size */
- tag = new int_label(0); tag.set_opaque(true);
- tag.set_part_a_constraint(
- std_function.subtract(OTHER.OBJ(cut_x2).X(), OTHER.OBJ(cut_x1).X(), 1));
- result.add_child(tag);
-
- /* add separator label */
- tag = new label("x"); tag.set_opaque(true);
- result.add_child(tag);
-
- /* build int_label constrained to x size */
- tag = new int_label(0); tag.set_opaque(true);
- tag.set_part_a_constraint(
- std_function.subtract(OTHER.OBJ(cut_y2).Y(), OTHER.OBJ(cut_y1).Y(), 1));
- result.add_child(tag);
-
- return result;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Handle callbacks.
- */
- public void callback(interactor from, event evt, int cb_num, Object cb_parm)
- {
- /* clear out any old message */
- message.set_text("");
-
- /* is the callback a drag from one of the cutters? */
- if (from instanceof drag_container)
- {
- /* make sure cutters are in bounds and in order */
- fix_cut_bounds(from);
- }
-
- /* is the callback from the load button */
- else if (from == load_button)
- {
- /* load the image */
- load_image(load_name.text());
-
- /* force cutter positions into new bounds */
- fix_cut_bounds(null);
- }
-
- /* is the callback from the save button */
- else if (from == save_button)
- {
- save_image(save_name.text());
- }
-
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Make sure cutters in in bounds and in order */
- protected void fix_cut_bounds(interactor from)
- {
- /* force everyone to be in bounds */
- if (cut_x1.x() < border) cut_x1.set_x(border);
- if (cut_x2.x() < border) cut_x2.set_x(border);
- if (cut_x1.x() > the_image.w()-1+border)
- cut_x1.set_x(the_image.w()-1+border);
- if (cut_x2.x() > the_image.w()-1+border)
- cut_x2.set_x(the_image.w()-1+border);
- if (cut_y1.y() < border) cut_y1.set_y(border);
- if (cut_y2.y() < border) cut_y2.set_y(border);
- if (cut_y1.y() > the_image.h()-1+border)
- cut_y1.set_y(the_image.h()-1+border);
- if (cut_y2.y() > the_image.h()-1+border)
- cut_y2.set_y(the_image.h()-1+border);
-
- /* reorder if dragged cutter crosses its mate */
- if (from == cut_x1 && cut_x1.x() > cut_x2.x())
- cut_x1.set_x(cut_x2.x());
- else if (from == cut_x2 && cut_x1.x() > cut_x2.x())
- cut_x2.set_x(cut_x1.x());
- else if (from == cut_y1 && cut_y1.y() > cut_y2.y())
- cut_y1.set_y(cut_y2.y());
- else if (from == cut_y2 && cut_y1.y() > cut_y2.y())
- cut_y2.set_y(cut_y1.y());
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Load image from given location (a URL) */
- protected void load_image(String name)
- {
- /* load the image */
- try {
- the_image.set_image(manager.load_image(new URL(name)));
- } catch(MalformedURLException ex) {
- /* Couldn't load, so use the broken image icon */
- the_image.set_image(std.broken_image_icon());
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Write image (as subArctic static init code) into file with given name */
- protected void save_image(String name)
- {
- String image_name;
- PrintStream fil;
- int size_w, size_h;
- PixelGrabber grabber;
- int[] pixels;
- int i, cnt, pos;
- long pix;
-
- /* try to open the named file */
- try {
- fil = new PrintStream(new FileOutputStream(name));
- } catch (IOException ex) {
- message.set_text("Can't open \"" + name + "\" for output.");
- return;
- } catch (SecurityException ex2) {
- message.set_text("Security Exception: " +
- "Sorry, can't write files under the current security settings.");
- return;
- }
-
- /* trim off leading directory components from file name */
- image_name = name;
- pos = image_name.lastIndexOf("/");
- if (pos != -1) image_name = image_name.substring(pos+1);
-
- /* trim off trailing suffix from file name */
- pos = image_name.lastIndexOf(".");
- if (pos != -1) image_name = image_name.substring(0,pos);
-
- /* measure the cut */
- size_w = cut_x2.x() - cut_x1.x() + 1;
- size_h = cut_y2.y() - cut_y1.y() + 1;
- pixels = new int[size_w*size_h];
-
- /* pull out the pixels being reguested */
- grabber = new PixelGrabber(the_image.image().image(),
- cut_x1.x(), cut_y1.y(), size_w, size_h, pixels, 0, size_w);
- try {
- grabber.grabPixels();
- } catch (InterruptedException ex) {
- message.set_text("Pixel cut failed do to \"Interrupted Exception\"");
- return;
- }
-
- /* check that it really worked. */
- if ((grabber.status() & ImageObserver.ABORT) != 0)
- {
- message.set_text("Error or abort in grabbing pixels");
- return;
- }
-
- /* write out first part of code */
- fil.println(" // (generated from image_cutter)");
- fil.println(" protected static int "+image_name+"_width = " +size_w+";");
- fil.println(" protected static int "+image_name+"_height = "+size_h+";");
- fil.println(" protected static int[] "+ image_name+"_data = {");
-
- /* indent */
- fil.print(" ");
-
- /* write out each pixel */
- cnt = 0;
- for (i = 0; i < size_w*size_h; i++)
- {
- /* write pixel in unsigned hex */
- pix = pixels[i];
- pix &= 0xffffffffL;
- fil.print("0x" + Long.toString(pix, 16));
- if (i != size_w*size_h-1)
- {
- fil.print(",");
- }
-
- /* break the line after 6th value */
- cnt++;
- if (cnt == 6)
- {
- /* end line and indent */
- fil.println();
- fil.print(" ");
- cnt = 0;
- }
- }
-
- /* do the rest of the code */
- fil.println("};");
- fil.println(" protected static sub_arctic.output.loaded_image _" +
- image_name + " = null;");
- fil.println();
- fil.println(" public static sub_arctic.output.loaded_image " +
- image_name + "() {");
- fil.println(" if (_" + image_name + " == null)");
- fil.println(" _"+image_name+" = new sub_arctic.output.loaded_image("
- +image_name+"_data,");
- fil.println(" "+image_name+"_width,"+image_name+"_height);");
- fil.println(" return _"+image_name+";");
- fil.println(" }");
-
- message.set_text(size_w + "x" + size_h + " image written to \"" +
- name + "\".");
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- }
-
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-