Sử dụng phương thức getImage()
Lớp Applet cung cấp hai phương thức getImage(): • public Image getImage(URL url)
• public Image getImage(URL url, String name)
Chỉ có Applets mới có thể sử dụng phương thức getImage(). Hơn thế nữa, phương thức getImage() của Applet không làm việc cho đến khi nào Applet có một ngữ cảnh đầy đủ. Vì lí do này, những phương thức này không làm việc nếu nó được gọi trong một cấu trúc hoặc câu lệnh khai báo một biến minh hoạ. Bạn nên gọi phương thức init() thay vì gọi phương thức getImage(). Đoạn lệnh sau miêu tả việc sử dụng phương thức getImage() của Applet.
//In a method in an Applet subclass:
Image image1 = getImage(getCodeBase(), "imageFile.gif");
Image image2 = getImage(getDocumentBase(), "anImageFile.jpeg");
Image image3 = getImage(new
URL("http://java.sun.com/graphics/people.gif")); Lớp Toolkit khai báo hơn hai phương thức getImage():
• public abstract Image getImage(URL url)
• public abstract Image getImage(String filename)
bạn có thể nhận đối tượng Toolkit bằng cách gọi phương thức getDefaultToolkit() của lớp Toolkit hoặc gọi phương thức getToolkit() của các thành phần. Phương thức getToolkit() của thành phần trả về đối tượng Toolkit được sử dụng (hoặc sẽ được sử dụng) dể thực thi một thành phần.
Sau đây là ví dụ minh hoạ việc sử dụng phương thức getImage() của Toolkit. Mỗi ứng dụng và Applet của Java có thể sử dụng các phương thức này, với Applet thwongf hạn chế vấn đề về bảo mật. Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image1 = toolkit.getImage("imageFile.gif");
Image image2 = toolkit.getImage(new
URL("http://java.sun.com/graphics/people.gif"));
Yêu cầu và theo đõi quá trình nạp ảnh: MediaTracker và ImageObserver
AWT cung cấp hai cách thức cho việc theo dõi quá trình nạp ảnh: lớp MediaTracker và giao diện ImageObserver. Lớp MediaTracker đầy đủ cho mọi chương trình. Bạn có thể tạo một MediaTracker, và lệnh cho nó theo dõi một hoặc nhiều ảnh, và rồi yêu cầu nó cho biết tình trang cảu các ảnh này khi cần thiết.
Giao diện ImageObserver cho phép bạn theo dõi sát nút hơn quá trình nạp ảnh so với lớp MediaTracker cho phép. Lớp tahnhf phần này sử dụng nó do đó các thành phần này vẽ lại các ảnh ngay sau khi ảnh được nạp. Để sử dụng giao diện ImageObserver, bạn thực thi phương thức imageUpdate() của ImageObserver và chắn chắn rằng các đối tượng thực thi phương thức đó được đăng kí như là một giao diện ImageOserver. Thôgn thường, sự đăng kí xảy ra khi bạn xác định một ImageObserver cho phương thức drawImage. Phương thức imageUpdate() được gọi bất cứ khi nào có các thông tin về ảnh Đây là một ví dụ thực thi phương thức imageUpdate()của giao diện Image Observer. Ví dụ này sử dụng phương thức imageUpdate() đẻ xác định vị trí của hai bức ảnh nagy sau khi biết kích thước của nó, và cử 100 milliseconds là vẽ lại nó cho đến khi nó được nạp hoàn chỉnh.
public boolean imageUpdate(Image theimg, int infoflags, int x, int y, int w, int h) { if ((infoflags & (ERROR)) != 0) {
errored = true; }
if ((infoflags & (WIDTH | HEIGHT)) != 0) { positionImages();
}
boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0);
// Repaint immediately if we are done, otherwise batch up // repaint requests every 100 milliseconds
repaint(done ? 0 : 100);
}
Tạo ảnh với MemoryImageSource
Với sự trợ giúp của lớp MemoryImageSource, bạn có thể dễ dàng tạo ảnh. Đoạn lệnh ví dụ sau vẽ một ảnh kích thước 100x100 hiển thị mờ đi từ màu đen cho đến màu xanh theo trục X và mờ đi từ đen đến đỏ theo trục Y.
int w = 100; int h = 100;
int[] pix = new int[w * h]; int index = 0;
for (int y = 0; y < h; y++) { int red = (y * 255) / (h - 1); for (int x = 0; x < w; x++) {
int blue = (x * 255) / (w - 1);
pix[index++] = (255 << 24) | (red << 16) | blue; }
}
Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));
Hiển thị ảnh
Sau đây là đoạn ví dụ minh hoạ việc hiển thị ảnh tại vị trí (0, 0) ở vùng quản lí của thành phần: g.drawImage(image, 0, 0, this);
sau đây là ví dụ minh hoạ việc hiển thị ảnh với 300 pixel chiều rộng và 62 pixel chiều cao, và bắt đầu từ vị trí (90, 0):
g.drawImage(myImage, 90, 0, 300, 62, this);
Lớp Graphics khai báo phương thức drawImage() sau. Tất cả đều trả về giá trị Boolean, mặc dù giá trị này hiếm khi được sử dụng. Giá trị là true nếu ảnh đã hoàn toàn được nạp và haong toàn được vẽ; nếu khác, giá trị là false.
• public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer)
• public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer)
• public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer)
• public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)
Những phương thức drawImage()có các thông số sau: Image img
Ảnh được vẽ. int x, int y Vị trí vẽ của ảnh.
int width, int height
Chiều rộng và chiều cao của ảnh được vẽ. Color bgcolor
Màu được vẽ bên dưới của ảnh. Nó có thể cần thiết nếu ảnh chứa các pixel trong suốt. ImageObserver observer
Đối tượng thực thi giao diện ImageObserver. Nó đăng kí đối tượng như là một ImageObserver vì thế nó không được thông báo bất cứ lúc nào mà có thông tin về ảnh. Mọi thành phần có thể đơn giản xác định vấn đề này.
Lí do mà nó chỉ làm việc như là ImageObserver là vì lớp thành phần thực thi giao diện ImageObserver. Phương thức drawImage() trả về sau khi hiển thị ảnh hoàn toàn.
Hình ảnh trên minh hoạ dữ liệu ảnh được tạo như thế nào. Một image producer -- một đối tưong gắn chặt với giao diện ImageProducer – đưa ra một dữ liệu thô cho đối tượng Image. Image producer cung cấp dữ liệu này cho một image consumer -- một đối tương gắn chặt với giao diện ImageConsumer. Trừ khi bạn cần thiết phải chế tác hay tạo một hình ảnh cho mình, nếu không bạn không cần biết về image producers và consumers. AWT tự động sử dụng Image producers và consumers.
AWT cung cấp công cụ chế tác ảnh bằng cách cho phép bạn chèn Image filters giữa các image producers và image consumers. Một image filter là một đối tượng ImageFilter có thể nằm giữa producer và consumer, sửa đổi dữ liệu ảnh trươvs khi consumer nhận nó. ImageFilter thực thi một giao diện ImageConsumer, từ khi image filters ngăn chặn các thông điệp mà producer gửi tới consumer. Hình sau minh hoạ image filter được đặt như thế nào ở giữa image producer và consumer.
Sử dụng Image Filter
Applet sau sử dụng một filter để quay một ảnh.
public class ImageRotator extends Applet { . . .
RotatorCanvas rotator;
double radiansPerDegree = Math.PI / 180; public void init() {
//Load the image.
Image image = getImage(getCodeBase(), "../images/rocketship.gif");
...//Create the component that uses the image filter:
rotator = new RotatorCanvas(image); . . .
add(rotator); . . .
}
public boolean action(Event evt, Object arg) { int degrees;
...//Get the number of degrees to rotate the image by.
//Convert to radians.
rotator.rotateImage((double)degrees * radiansPerDegree); return true;
} }
class RotatorCanvas extends Canvas { Image sourceImage;
Image resultImage;
public RotatorCanvas(Image image) { sourceImage = image;
resultImage = sourceImage; }
public void rotateImage(double angle) {
ImageProducer producer = new FilteredImageSource( sourceImage.getSource(), filter); resultImage = createImage(producer); repaint(); }
public void paint(Graphics g) { Dimension d = size();
int x = (d.width - resultImage.getWidth(this)) / 2; int y = (d.height - resultImage.getHeight(this)) / 2; g.drawImage(resultImage, x, y, this);
} }
Đoạn lệnh trên làm việc như thế nào
1. nhận một đối tượng Image (thông thường dùng phương thức getImage()).
2. Sử dụng phương thức getSource(), lấy dữ liệu (ImageProducer) cho đối tượng Image 3. tạo một mô tả của Image filter, khởi tạo filter khi cần thiết.
4. Tạo một đối tượng FilteredImageSource, bỏ qua cấu trúc của dữ liệu ảnh và đối tượng Filter. 5. Với phương thức createImage(), tạo mới một đối tượng Image có một FilteredImageSource như là một Image producer.
Trong ví dụ trên, phương thức rotateImage() của RotatorCanvasmethod thực thi các nhiệm vụ có quan hệ với việc sử dụng Image filter. Trừ bước đầu tiên ra, lấy đối tương Image thô, thực hiện bởi phương thức init() của Applet. Đối tượng Image này được chuyển tới RotatorCanvas, được đề cập tới như là sourceImage.
Phưong thức rotateImage() thuyết minh cho image filter bằng cách gọi cấu trúc của Filter. Thông số cho cấu trúc này là một gócmà ảnh quay.
ImageFilter filter = new RotateFilter(angle);
Kế tiếp, phương thức rotateImage() tạo một minh hoạ FilteredImageSource của. thông số thứ nhất cho cấu trúc FilteredImageSource là nguồn ảnh, lấy được qua phương thức getSource(). Thông số thứ hai là đối tượng Filter.
ImageProducer producer = new FilteredImageSource(
sourceImage.getSource(), filter);
Cuối cùng, câu lệnh tạo ảnh thứ hai, resultImage, bằng việc sử dụng phương thức createImage() của thành phần. Thông số duy nhất createImage() là FilteredImageSource được tạo bởi bước trên.
resultImage = createImage(producer);
Viết một Image Filter
Tất cả các Image Filter phải là các lớp con của lớp ImageFilter. Nếu image filter sẽ được sửa đổi màu hoặc các Pixel trong suốt của ảnh, thì thay vì phải tạo trực tiếp một lớp con của ImageFilter, bạn có thể tạo một lớp con của RGBImageFilter.
Tạo một lớp con ImageFilter
Như đã đề cập ở phần trước, các Image filter thực thi giao diện ImageConsumer. ImageConsumer định nghĩa các phương thức sau:
void setDimensions(int width, int height); void setProperties(Hashtable props);
void setColorModel(ColorModel model); void setHints(int hintflags);
void setPixels(int x, int y, int w, int h, ColorModel model, byte pixels[], int off, int scansize);
void setPixels(int x, int y, int w, int h, ColorModel model, int pixels[], int off, int scansize);
void imageComplete(int status);
Lớp ImageFilter thực thi tất cả các phương thức trên. Ví dụ, ImageFilter thực thi phương thức setDimensions() như sau:
public void setDimensions(int width, int height) { consumer.setDimensions(width, height);
}
Nhờ các phương thức của ImageFilter này, lớp con của bạn có thể không cần đến việc phải thực thi mọi phương thức của ImageConsumer. bạn chỉ cần thực thi một phương thức để chuyển giao dữ liệu mà bạn muốn thay đổi.
Ví dụ, lớp CropImageFilter thực thi bốn phương thức: setDimensions(), setProperties(), và hai loại phương thức setPixels(). Nó cũng thực thi một cấu trúc với thông số là hình chữ nhật xác định cho việc cắt xén. Ví dụ khác, lớp RGBImageFilter thực thi vài phương thức trợ giúp, định nghĩa một phưong thức giúp đỡ trừu tượng để thực hiện việc thay đổi màu thật của mỗi pixel, và thực thi các phương thức sau của ImageConsumer: setColorModel() và hai loại phương thức setPixels().
Hầu hết Most, các filter thực thi những phương thức setPixels(). những phương thức này xác định chính xác dữ liệu ảnh được dùng để xây dựng một Image. một hoặc hai phương thức setPixels() có thể được gọi nhiều lần trong suốt quá trình xây dựng một Image. Mỗi lần gọi đều đưa tới ImageConsumer thông tin vùng bao hình chữ nhật của ảnh. Khi phương thức imageComplete() của ImageConsumer được gọi với mọi trạng thái trừ SINGLEFRAMEDONE, thì ImageConsumer có thể thừa nhận là nó có không thể nhận hơn nữa phương thức setPixels(). Một trạng thái imageComplete() của STATICIMAGEDONE xác định rằng không chỉ đã hoàn toàn nhận đầy đủ dữ kiệu ảnh, mà còn xác định rằng không có lỗi nào xảy ra.
Hình ảnh minh hoạ và bảng sau mô tả cá c phương thức setPixels() và các thông số cho các phương thức đó.
x, y
Xác định vị trí của ảnh w, h
Xác định chiều rộng và chiều cao cho mỗi vùng hình chữ nhật. model
Xác định kiểu màu được sử dụng cho các Pixel. pixels[]
Xác định một mảng các Pixel. Vùng bao hình chữ nhật của ảnh nằm trong mảng các Pixel này, nhưng mảng phải chứa hơn giá trị w*h hiện tại, phụ thuộc vào giá trị của offset và scansize. Sau đây là công thức tính cho việc xác định mảng các Pixel hiện tại của dữ liệu tại (x+i, y+j), nơi (0 <= i < w) và (0 <= j < h):
offset
xác định vị trí (trong mảng các pixels) của pixel đầu tiên trong vùng bao hình chữ nhật. scansize
xác định chiều rông cho mỗi hàng của mảng các pixels..
The RotateFilter Image Filter
Lớp RotateFilter quay một ảnh bởi một góc xác định. Nó dựa vào công thức hình học để tính vị trí cho mỗi pixel:
newX = oldX*cos(angle) - oldY*sin(angle) newY = oldX*sin(angle) + oldY*cos(angle) RotateFilter thực thi các phương thức sau của ImageConsumer: setDimensions()
Ghi lại chiều rộng và chiều cao của ảnh không được lọc trong phương thức setPixels() và imageComplete(). Tính chiều cao cuối cùng ảnh được lọc, ghi lại dùng cho việc sử dụng phương thức imageComplete() của nó, tạo một bộ đệm để chứa dữ liệu ảnh khi nó lọc được và gọi phương thức setDimensions() để xác lập chiều cao và chiều rộng mới.
setColorModel()
Nói cho biết các Pixel sử dụng màu của RGB. setHints()
Xác định ảnh đã được sắp xếp thứ tự theo hàng và cột. setPixels() (cả hai loại của phương thức này)
Chuyển đổi các Pixel sang kiểu RGB mặc định (nếu cần thiết) và sao chép các Pixel đó sang bộ đệm. imageComplete()
Quay ảnh rồi gọi phương thức consumer.setPixels()gửi liên tục từng hàng của ảnh đến Consumer. Sau khi đã gửi hết, phương thức này gọi đến consumer.imageComplete().