Лабораторная_работа_2. Лабораторная работа Разработка абстрактного базового класса
Скачать 80.5 Kb.
|
Лабораторная работа 2. Разработка абстрактного базового классаРазработать абстрактный базовый класс графического объекта с данными и функционалом (абстрактными и переопределяемыми методами): координаты центра и размеры охватывающего прямоугольника, цвет, рисование объекта, проверка на принадлежность точки объекту, запись/чтение в различные потоки, а также все остальные, необходимые для реализации функционала в последующих работах. Разработать два производных класса (по вариантам). Разработать оконное приложение с созданием и уничтожением объектов по координатам клика мыши. Объекты сохраняются в векторе в виде ссылок на базовый класс. Варианты заданий
План:
import java.util.*; import java.awt.Graphics; import java.awt.Color; import java.awt.Point;
public abstract class Figure { public abstract void paint(Graphics g); public abstract boolean infigure(int x1, int y1); }
.drawRect(x,y,w,h); .drawLine(x1,y1,x2,y2); .drawOval(x,y,w,h); .drawImage(img, x, y, null); .setColor(Color c); .setColor(Color.black); .setColor(canvas1.getBackground()); .getColor(); 6. Обработка события кнопки мыши private void canvas1MouseClicked(java.awt.event.MouseEvent evt) { int X,Y, i=0, sw; Graphics gg; Figure fig; X=evt.getX(); Y=evt.getY(); gg = canvas1.getGraphics(); sw=evt.getButton(); if (sw==1) { //Left mouse button gg.setColor(Color.black); if(choice1.getSelectedItem()=="Звезды"){ star = new Star(Integer.parseInt(textField1.getText()),5,20,X,Y); al.add(star); star.paint(gg); } if(choice1.getSelectedItem()=="Текст"){ txt = new Words(textField2.getText(),X,Y); al.add(txt); txt.paint(gg); } } if (sw==3) { //Right mouse button gg.setColor(canvas1.getBackground()); while (i < al.size()){ // System.out.println("Size="+al.size()); fig=al.get(i); if(fig.infigure(X, Y)){ fig.paint(gg); al.remove(i); } i++; } } } http://docs.oracle.com/javase/tutorial/2d/images/loadimage.html Reading/Loading an ImageWhen you think of digital images, you probably think of sampled image formats such as the JPEG image format used in digital photography, or GIF images commonly used on web pages. All programs that can use these images must first convert them from that external format into an internal format. Java 2D supports loading these external image formats into its BufferedImage format using its Image I/O API which is in the javax.imageio package. Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP. Image I/O is also extensible so that developers or administrators can "plug-in" support for additional formats. For example, plug-ins for TIFF and JPEG 2000 are separately available. To load an image from a specific file use the following code, which is from LoadImageApp.java: BufferedImage img = null; try { img = ImageIO.read(new File("strawberry.jpg")); } catch (IOException e) { } Image I/O recognises the contents of the file as a JPEG format image, and decodes it into a BufferedImage which can be directly used by Java 2D. LoadImageApp.java shows how to display this image. If the code is running in an applet, then its just as easy to obtain the image from the applet codebase. The following excerpt is from LoadImageApplet.java: try { URL url = new URL(getCodeBase(), "examples/strawberry.jpg"); img = ImageIO.read(url); } catch (IOException e) { } The getCodeBase method used in this example returns the URL of the directory containing this applet when the applet is deployed on a web server. If the applet is deployed locally, getCodeBase returns null and the applet will not run. The following example shows how to use the getCodeBase method to load the strawberry.jpg file. Note: If you don't see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release. LoadImageApplet.java contains the complete code for this example and this applet requires the strawberry.jpg image file. In addition to reading from files or URLS, Image I/O can read from other sources, such as an InputStream. ImageIO.read() is the most straightforward convenience API for most applications, but the javax.imageio.ImageIO class provides many more static methods for more advanced usages of the Image I/O API. The collection of methods on this class represent just a subset of the rich set of APIs for discovering information about the images and for controlling the image decoding (reading) process. We will explore some of the other capabilities of Image I/O later in the Writing/Saving an Image section. Drawing an ImageAs you have already learned, the Graphics.drawImage method draws an image at a specific location: boolean Graphics.drawImage(Image img, int x, int y, ImageObserver observer); The x,y location specifies the position for the top-left of the image. The observer parameter notifies the application of updates to an image that is loaded asynchronously. Theobserver parameter is not frequently used directly and is not needed for the BufferedImage class, so it usually is null. The described method addresses only the case where the entire image is to be drawn, mapping image pixels to user space coordinates 1:1. Sometimes applications require to draw a part of the image (a sub-image), or scale the image to cover a particular area of the drawing surface, or transform or filter the image before drawing. The overloads of the drawImage() method perform these operations. For example, the following overload of the drawImage() method enables you to draw as much of a specified area of the specified image as is currently available, scaling it to fit inside the specified area of the destination drawable surface: boolean Graphics.drawImage(Image img, int dstx1, int dsty1, int dstx2, int dsty2, int srcx1, int srcy1, int srcx2, int srcy2, ImageObserver observer); The src parameters represent the area of the image to copy and draw. The dst parameters display the area of the destination to cover by the the source area. The dstx1, dsty1 coordinates define the location to draw the image. The width and height dimensions on the destination area are calculated by the following expressions: (dstx2-dstx1), (dsty2-dsty1). If the dimensions of the source and destinations areas are different, the Java 2D API will scale up or scale down, as needed. The following code example divides an image into four quadrants and randomly draws each quadrant of the source image into a different quadrant of the destination. Note: If you don't see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release. The complete code for this applet is in JumbledImageApplet.java. This example uses the following code to paint the jumbled duke_skateboard.jpg image. It iterates over the four sub-images of the source, drawing each in turn into a randomly selected destination quadrant. /* divide the image 'bi' into four rectangular * areas and draw each of these areas in to a * different part of the image, so as to jumble * up the image. 'cells' is an array which has * been populated with values which redirect * drawing of one subarea to another subarea. */ int cellWidth = bi.getWidth(null)/2; int cellHeight = bi.getHeight(null)/2; for (int x=0; x<2; x++) { int sx = x*cellWidth; for (int y=0; y<2; y++) { int sy = y*cellHeight; int cell = cells[x*2+y]; int dx = (cell / 2) * cellWidth; int dy = (cell % 2) * cellHeight; g.drawImage(bi, dx, dy, x+cellWidth, dy+cellHeight, sx, sy, sx+cellWidth, sy+cellHeight, null); } } Filtering ImagesIn addition to copying and scaling images, the Java 2D API also filter an image. Filtering is drawing or producing a new image by applying an algorithm to the pixels of the source image. Image filters can be applied by using the following method: void Graphics2D.drawImage(BufferedImage img, BufferedImageOp op, int x, int y) The BufferedImageOp parameter implements the filter. The following applet represents an image drawn on top of text. Drag the slider to show more or less of the text through the image and make the image more or less transparent. Note: If you don't see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release. The following code shows how the filter action is done by operating on a BufferedImage object with an alpha channel and rescales that alpha channel by using theRescaleOp object. The alpha channel determines the translucency of each pixel. It also specifies the degree to which this image overwrites. /* Create an ARGB BufferedImage */ BufferedImage img = ImageIO.read(imageSrc); int w = img.getWidth(null); int h = img.getHeight(null); BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.getGraphics(); g.drawImage(img, 0, 0, null); /* * Create a rescale filter op that makes the image * 50% opaque. */ float[] scales = { 1f, 1f, 1f, 0.5f }; float[] offsets = new float[4]; RescaleOp rop = new RescaleOp(scales, offsets, null); /* Draw the image, applying the filter */ g2d.drawImage(bi, rop, 0, 0); The complete example represented in SeeThroughImageApplet.java includes the code that uses the slider to adjust the transparency from the initial 50%. This example also requires the duke_skateboard.jpg image. The RescaleOp object is just one of many filters that can be created. The Java 2D API has several built in filters including the following:
The following example uses each of the described filters as well as scaling: Note: If you don't see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release. The complete code for this applet is in ImageDrawingApplet.java and this applet requires the bld.jpg image. Use the drop-down menu to select an image scaling or filtering operation. Creating and Drawing to an ImageWe already know how to load an existing image, which was created and stored in your system or in any network location. But, you probably would like also to create an new image as a pixel data buffer. In this case, you can create a BufferedImage object manually, using three constructors of this class:
On the other hand, we can use methods of the Component class. These methods can analyze the display resolution for the given Component or GraphicsConfigurationand create an image of an appropriate type.
GraphicsConfiguration returns an object of BufferedImage type, but the Component returns an object of Image type, if you need a BufferedImage object instead then you can perform an instanceof and cast to a BufferedImage in your code. As was already mentioned in the previous lessons, we can render images not only on screen. An images itself can be considered as a drawing surface. You can use acreateGraphics() method of the BufferedImage class for this purpose: ... BufferedImage off_Image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = off_Image.createGraphics(); Another interesting use of offscreen images is an automaticdouble buffering. This feature allows to avoid flicker in animated images by drawing an image to a back buffer and then copying that buffer onto the screen instead of drawing directly to the screen. Java 2D also allows access to hardware acceleration for offscreen images, which can provide the better performance of rendering to and copying from these images. You can get the benefit of this functionality by using the following methods of the Image class:
Writing/Saving an ImageThis lesson started with an explanation for using the javax.imageio package, to load images from an external image format into the internal BufferedImage format used by Java 2D. Then it explains how to use the Graphics.drawImage() to draw that image, with optional filtering. The final stage is saving a BufferedImage object into an external image format. This may be an image that was originally loaded by the Image I/O class from an external image format and perhaps modified using the Java 2D APIs, or it may be one that was created by Java 2D. The Image I/O class provides a simple way to save images in a variety of image formats in the following example: static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException Note: The BufferedImage class implements the RenderedImage interface. . The formatName parameter selects the image format in which to save the BufferedImage. try { // retrieve image BufferedImage bi = getMyImage(); File outputfile = new File("saved.png"); ImageIO.write(bi, "png", outputfile); } catch (IOException e) { ... } The ImageIO.write method calls the code that implements PNG writing a “PNG writer plug-in”. The term plug-in is used since Image I/O is extensible and can support a wide range of formats. But the following standard image format plugins : JPEG, PNG, GIF, BMP and WBMP are always be present. Each image format has its advantages and disadvantages:
For most applications it is sufficient to use one of these standard plugins. They have the advantage of being readily available. The Image I/O class provides a way to plug in support for additional formats which can be used, and many such plug-ins exist. If you are interested in what file formats are available to load or save in your system, you may use the getReaderFormatNames and getWriterFormatNames methods of the ImageIO class. These methods return an array of strings listing all of the formats supported in this JRE. String writerNames[] = ImageIO.getWriterFormatNames(); The returned array of names will include any additional plug-ins that are installed and any of these names may be used as a format name to select an image writer. The following code example is a simple version of a complete image edit/touch up program which uses a revised version of the ImageDrawingApplet.java sample program which can be used as follows :
The complete code of this example is represented in SaveImage.java. In this lesson you have learned just the basics of Image I/O, which provides extensive support for writing images, including working directly with an ImageWriter plug-in to achieve finer control over the encoding process. ImageIO can write multiple images, image metadata, and determine quality vs. size tradeoffs. For more information see Java Image I/O API Guide. |