back
GraphicPad Source Code
/**
* File: gpPictureStudio4.java
* Author: Joseph Dever
* Contact: jdever@cs.umb.edu
* Date: March 10, 2001
* Copyright 2001 JDever
*
* Plug-in GraphicPad Component that runs with Paintlet.
* Creates an oval frame around an image. Frame's texture is
* created with image files supplied with the component.
* Parameters: picture image, textureFile, frame color
*
* Notes: -components are packaged in jar files and loaded from Paintlet
* using JarFileClassloader class
* -component is in default package
* -naming collisions are avoided since classes are loaded first
* from the jar file
* -information on the GraphicPad architecture and APIs in
* Javadoc format are available at www.cs.umb.edu/~jdever
* March 27, 2002
*/
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.jar.*;
_public class gpPictureStudio4 extends GpadComponent {
_
____ String componentFileName = "gpPictureStudio4.jar";
_
____ //jarfile containing this component class
____ JarFile jfile = null;
_
____ //a check for essential user-supplied parameters
____ boolean ready;
_
____ //paintlet canvas class
____ BufferedImage offScreen = null;
_
____ //texture image
____ Image tileImage = null;
____
____ //picture image created from user-supplied File parameter
____ Image picture = null;
_
____ //used to alter alpha channel of picture image
____ BufferedImage mask = null;
_
____ MediaTracker tracker;
_
____ //colors that define user-supplied color theme
____ Color highliteColor,midtoneColor,shadowColor;
_
____ //centers picture on paintlet canvas and
____ //scales to fit if needed
____ int picX,picY,picWidth,picHeight;
_
____ //border space on left and right of picture
____ int border = 60;
_
____ //parameters, values supplied by user through gpad GUI
____ File pictureFile;
____ String texture = "";
____ String colorTheme = "";
_
____ /**
_____ * Initializes component by adding zero or more parameters. Creates
_____ * a handle to component by obtaining a reference to the component
_____ * JarFile. Additional resources can be obtained from the JarFile
_____ * with the component handle. User tips may be added in either
_____ * String or Image format, which are displayed to the user
_____ * before runComponent is called.
_____ *
_____ */
_
____ public void initComponent() {
_______ parameters = true;
_______ addParameter("picture",GpadParm.IMAGE);
_______ addParameter("texture",GpadParm.VARIABLE);
_______ addParameter("textureColor",GpadParm.VARIABLE);
_
_______ File f = new File(new File("Components"),componentFileName);
_______ try {
__________ jfile = new JarFile(f);
_______ }catch(IOException ioe10) {
__________ //System.out is normally redirected to the file bugReport.
__________ System.out.println("Error reading jarFile. " + ioe10.toString());
________ }
_
_______ String tip = "PictureStudio4: Copyright 2001 JDever" + '\n' + "This GraphicPad component will
__________________add an oval border to" + '\n' + "a picture.";
_______ gpSetTips(tip);
_______ showTips();
____ }//initComponent.
_
____ /**
_____ * Gets values for user-supplied parameters. Executes operations on
_____ * the paintlet canvas. See the GpadComponent, GpadFilter and GpadCurve
_____ * APIs for a list of available operations.
_____ *
_____ */
_
____ public void runComponent() {
_______ ready = true;
_
_______ //width and height of paintlet canvas
_______ int w = GpadParm.WIDTH;
_______ int h = GpadParm.HEIGHT;
_
_______ //texture image fileSize
_______ int fileSize = 0;
_
_______ //paintlet canvas, can be used to perform operations not
_______ //available in the GpadComponent API
_______ offScreen = (BufferedImage)gpGetCanvasImage();
_
_______ //gparm object contains parameter values supplied by the user.
_______ //this object is created in the Gpad application and a reference
_______ //to it is returned by this method.
_______ GpadParm gparm = getGpadParm();
_
_______ try {
_________ pictureFile = (File)gparm.getParmValue("picture");
_________ colorTheme = (String)gparm.getParmValue("textureColor");
_________ texture = (String)gparm.getParmValue("texture");
_______ }catch(GpadParmException gpe) {
__________ /*
____________ GpadParmException thrown if requested parm value does not exist.
____________ In this case, the component will do nothing, as the drawing
____________ operations are enclosed in an if(ready) block, however, default
____________ parameter values could be assigned here and the component could
____________ run with these. NOTE: exception is thrown if any of the parameters
____________ do not return values, so if the first parm does not have a value,
____________ the next two parms will not be assigned, as the getParmValue method
____________ will not be called in the try block.
__________ */
__________ ready = false;
__________ gpe.showMessage();
________ }//catch.
_
_______ if(!pictureFile.exists()) {
__________ ready = false;
_______ }
_
_______ /*
_________ The user-supplied colorTheme defines three colors,
_________ which are used in the FilterToneAdjust filter operation.
_________ This operation is carried out on the paintlet canvas image
_________ after the texture image has been drawn to it.
_______ */
_
_______ createColorTheme(colorTheme);
_
_______ /*
_________ The user-supplied texture defines a texture file which
_________ is included in the component jar file. This textureFile is
_________ is assigned in the method.
_______ */
_
_______ createTexture(texture);
_
_______ /*
_________ Retrieve the picture and texture images. Get resize
_________ dimensions if pic is oversized.
_______ */
_
_______ if(ready) {
__________ //Retrieve the texture image.
__________ tileImage = getJarImage(jfile,textureFile,fileSize);
_
__________ picture = gpGetImage(pictureFile);
_
__________ picWidth = gpGetImageWidth(picture);
__________ picHeight = gpGetImageHeight(picture);
_
__________ //Gets scaled dimensions for picture if its width plus
__________ //border or height plus border exceeds paintlet canvas dims.
__________ if((picWidth+border) >= GpadParm.WIDTH) {
_____________ int oldWidth = picWidth;
_____________ float fw = (float)GpadParm.WIDTH/(float)picWidth;
_____________ picWidth = (int)(picWidth*fw) - (int)(fw*border);
_____________ picHeight = (int)(((float)picWidth/(float)oldWidth)*picHeight);
__________ }//if.
__________ if((picHeight+border) >= GpadParm.HEIGHT) {
_____________ int oldHeight = picHeight;
_____________ float fh = (float)GpadParm.HEIGHT/(float)picHeight;
_____________ picHeight = (int)(picHeight*fh) - (int)(fh*border);
_____________ picWidth = (int)(((float)picHeight/(float)oldHeight)*picWidth);
__________ }//if.
__________ picX = (GpadParm.WIDTH - picWidth)/2;
__________ picY = (GpadParm.HEIGHT - picHeight)/2;
_______ }//if ready.
_
_______ /*
_________ Prepare canvas background, paint the texture as a single
_________ tile, filter the canvas color, create oval mask, filter
_________ picture with mask, paint picture to canvas, detail the picture.
_______ */
_______ if(ready) {
__________ gpRestoreDefaults();
__________ newBackground(Color.black);
_
__________ //Texture image is scaled up to match the dimensions
__________ //of the picture. Part of this image will be visible
__________ //when the picture is drawn on top of it, forming
__________ //the textured picture frame.
__________ gpDrawImage(tileImage,picX,picY,picWidth,picHeight);
_
__________ //Creates filter based on the colorTheme colors. Filters the
__________ //paintlet canvas, which has the textured image drawn already.
__________ //Redraws filtered canvas at original coordinates.
__________ Color[] tones = {Color.black,shadowColor,midtoneColor,highliteColor,Color.white};
__________ float[] toneRanges = {1,1,1,1};
__________ ToneAdjustmentOp tao = new ToneAdjustmentOp(tones,toneRanges);
__________ BufferedImage toneImg = tao.filter(offScreen,null);
__________ gpDrawImage(toneImg,0,0);
_
__________ //Mask is byte_gray image with picture dimensions.
__________ //White (fully opaque) ellipse is drawn on black
__________ //(fully transparent) background.
__________ mask = makeImageMask(gpGetImageWidth(picture),gpGetImageHeight(picture));
__________ AlphaFilter af = new AlphaFilter(mask);
__________ //Changes the alpha channel of the picture so that central ellipse
__________ //is fully opaque and remainder is fully transparent. Transparent
__________ //region allows the textured image to show through, forming the frame.
__________ FilteredImageSource fis = new FilteredImageSource(picture.getSource(),af);
_
__________ //CreateImage method is from Component class. GpadComponent class
__________ //is NOT a subclass of Component. in order to call createImage with
__________ //a FilteredImageSource, a JButton is created, hackButton.
__________ tracker = new MediaTracker(hackButton);
__________ picture = hackButton.createImage(fis);
__________ tracker.addImage(picture,0);
__________ try {
_____________ tracker.waitForID(0);
__________ }catch(InterruptedException ie2) {
_____________ //System.out is normally redirected to the file bugReport.
_____________ System.out.println("Image Loading Error" + ie2.toString());
___________ }
_
__________ //Picture is drawn to the paintlet canvas with
__________ //new alpha channel.
__________ gpDrawImage(picture,picX,picY,picWidth,picHeight);
_
__________ //Outline picture oval.
__________ gpSetAntiAlias(true);
__________ gpSetColor(Color.black);
__________ gpSetFillShape(false);
__________ gpCircle(picX,picY,picWidth,picHeight);
__________ gpSetColor(Color.gray);
__________ gpCircle(picX,picY,picWidth-1,picHeight-1);
_
__________ //Outline picture frame.
__________ gpSetFillShape(false);
__________ gpSetColor(Color.white);
__________ gpRectangle(picX,picY,picWidth,picHeight);
__________ gpSetColor(Color.darkGray);
__________ gpLine(picX+1,picY+1,picX+picWidth-2,picY+1);
__________ gpLine(picX+picWidth-1,picY+1,picX+picWidth-1,picY+picHeight-1);
_
__________ //Calls repaint of the paintlet canvas.
__________ gpRepaint();
_______ }//if ready.
____ }//runComponent.
_
____ /**
_____ * Creates a Choice object for use with a GpadParm.VARIABLE type
_____ * parameter. The GraphicPad application calls this method if a
_____ * variable type parameter is added to the component. Method is
_____ * called when user selects the parameter and the Choice object
_____ * is displayed. More descriptive names should be used for textures.
_____ */
_
____ public Choice getVariableChoice(String s) {
_______ Choice ch = new Choice();
_______ //s argument must equal name of VARIABLE parm added
_______ //in the initComponent method.
_______ if(s.equals("textureColor")) {
__________ ch.add("Antique");
__________ ch.add("Firethorn");
__________ ch.add("Verde");
__________ ch.add("Aqua");
__________ ch.add("Lilac");
__________ ch.add("Dusk");
__________ ch.add("BlueHaze");
__________ ch.add("BlueGray");
__________ ch.add("RedGray");
__________ ch.add("RedHaze");
_______ }
_______ else if(s.equals("texture")) {
__________ ch.add("a");
__________ ch.add("b");
__________ ch.add("c");
__________ ch.add("d");
__________ ch.add("e");
__________ ch.add("f");
__________ ch.add("g");
_______ }
_______ return ch;
____ }//getVariableChoice.
_
____ /**
_____ * Creates a byte_gray image for use with an AlphaFilter. When used
_____ * with the AlphaFilter, the returned image will have fully transparent
_____ * pixels where the mask image is black, fully opaque pixels where
_____ * mask is white and intermediate alpha values where gray.
_____ */
_
____ private BufferedImage makeImageMask(int imgWidth,int imgHeight) {
_______ BufferedImage mask = new BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY);
_______ Graphics2D g = mask.createGraphics();
_______ g.setPaint(Color.black);
_______ g.fillRect(0,0,imgWidth,imgHeight);
_______ Ellipse2D ell = new Ellipse2D.Float(0,0,imgWidth,imgHeight);
_______ g.setPaint(Color.white);
_______ g.fill(ell);
_
______ return mask;
____ }//makeImageMask.
_
____ /**
_____ * Retrieves images from the component jar file. Returns null
_____ * if an exception occurs when reading from the jar file.
_____ */
_
____ private Image getJarImage(JarFile jfile,String fileName,int fileSize) {
_
_______ byte[] ba = new byte[fileSize];
_______ try {
__________ JarEntry je = jfile.getJarEntry(fileName);
__________ InputStream is = jfile.getInputStream(je);
__________ BufferedInputStream bis = new BufferedInputStream(is);
__________ bis.read(ba,0,fileSize);
_______ }catch(IOException ioe1) {
__________ //System.out is normally redirected to the file bugReport.
__________ System.out.println(ioe1.toString());
__________ return null;
________ }
________ catch(Exception e1) {
__________ System.out.println(e1.toString());
__________ return null;
________ }
_
_______ Image img = Toolkit.getDefaultToolkit().createImage(ba);
_
_______ MediaTracker tracker = new MediaTracker(null);
_______ tracker.addImage(img,0);
_______ try {
__________ tracker.waitForID(0);
_______ }catch(InterruptedException ie2) {
__________ //System.out is normally redirected to the file bugReport.
__________ System.out.println("Image Loading Error" + ie2.toString());
________ }
_
_______ /*
________ Images are loaded asynchronously, so createImage may return before
________ the entire image has been loaded. MediaTracker will notify when the
________ image has been fully loaded. MediaTracker observer must be a
________ Component, but GpadComponents are NOT subclasses of AWT Components.
________ The observer for MediaTracker is null, since it cannot be this
________ GpadComponent.
_
________ The following code pauses method execution until the image width
________ and height are non-negative. This does not guarantee that the image
________ has been fully loaded, but if width and height are non-negative,
________ it generally is. Maximum wait-time is 5 seconds, although only a
________ fraction of a second is normally required, even on very slow machines.
________ If image width and height do not become non-negative, ready boolean
________ will be false and the image will not be drawn if ready is checked.
________ A more definitive approach should be developed. jdever, 12-07-01.
_______ */
_
_______ TimerThread timer = new TimerThread();
_______ timer.start();
_______ while(timer.getTime() <= 5) {
_____________ ready = false;
_____________ if(gpGetImageWidth(img) >= 0 && gpGetImageHeight(img) >= 0) {
________________ ready = true;
________________ break;
_____________ }//if.
_______ }//while.
_______ timer.lapse();
_
_______ return img;
____ }//getJarImage.
____
____ /*
______ The colorTheme is defined by the three colors,
______ which are assigned in this method. A text file containing
______ color values could be packaged in the component jar file
______ for more flexible code.
____ */
____ private void createColorTheme(String colorTheme) {
_
_______ if(colorTheme.equals("Antique")) {
__________ highliteColor = new Color(156,135,64);
__________ midtoneColor = new Color(121,74,38);
__________ shadowColor = new Color(77,48,34);
_______ }
_______ else if(colorTheme.equals("Firethorn")) {
__________ highliteColor = new Color(248,102,30);
__________ midtoneColor = new Color(176,43,28);
__________ shadowColor = new Color(67,28,59);
_______ }
_______ else if(colorTheme.equals("Aqua")) {
__________ highliteColor = new Color(200,245,135);
__________ midtoneColor = new Color(161,225,200);
__________ shadowColor = new Color(64,128,198);
_______ }
_______ else if(colorTheme.equals("Verde")) {
__________ highliteColor = new Color(215,237,62);
__________ midtoneColor = new Color(182,131,64);
__________ shadowColor = new Color(128,92,31);
_______ }
_______ else if(colorTheme.equals("Lilac")) {
__________ highliteColor = new Color(255,165,135);
__________ midtoneColor = new Color(200,105,190);
__________ shadowColor = new Color(95,25,95);
_______ }
_______ else if(colorTheme.equals("Dusk")) {
__________ highliteColor = new Color(235,135,85);
__________ midtoneColor = new Color(158,75,45);
__________ shadowColor = new Color(100,65,100);
_______ }
_______ else if(colorTheme.equals("BlueHaze")) {
__________ highliteColor = new Color(104,121,228);
__________ midtoneColor = new Color(85,114,138);
__________ shadowColor = new Color(64,63,91);
_______ }
_______ else if(colorTheme.equals("RedHaze")) {
__________ highliteColor = new Color(225,50,50);
__________ midtoneColor = new Color(150,50,50);
__________ shadowColor = new Color(75,20,20);
_______ }
_______ else if(colorTheme.equals("RedGray")) {
__________ highliteColor = new Color(225,50,50);
__________ midtoneColor = new Color(200,225,200);
__________ shadowColor = new Color(50,35,35);
_______ }
_______ else if(colorTheme.equals("BlueGray")) {
__________ highliteColor = new Color(125,125,200);
__________ midtoneColor = new Color(225,225,200);
__________ shadowColor = new Color(35,35,50);
_______ }
____ }//createColorTheme.
____ /*
______ The textureFile name and size are assigned.
______ Actual texture file is loaded from the component jar file
______ in runComponent, after this method call.
____ */
____ private void createTexture(String texture) {
_
_______ if(texture.equals("a")) {
__________ textureFile = "gpPictureStudio4a.jpg";
__________ fileSize = 7297;
_______ }
_______ else if(texture.equals("b")) {
__________ textureFile = "gpPictureStudio4b.jpg";
__________ fileSize = 27066;
_______ }
_______ else if(texture.equals("c")) {
__________ textureFile = "gpPictureStudio4c.jpg";
__________ fileSize = 9946;
_______ }
_______ else if(texture.equals("d")) {
__________ textureFile = "gpPictureStudio4d.jpg";
__________ fileSize = 24166;
_______ }
_______ else if(texture.equals("e")) {
__________ textureFile = "gpPictureStudio4e.jpg";
__________ fileSize = 8008;
_______ }
_______ else if(texture.equals("f")) {
__________ textureFile = "gpPictureStudio4f.jpg";
__________ fileSize = 46390;
_______ }
_______ else if(texture.equals("g")) {
__________ textureFile = "gpPictureStudio4g.jpg";
__________ fileSize = 32100;
_______ }
_
____ }//createTexture.
_}//end of class.