Professional Documents
Culture Documents
Baocao A5 - Graphics2d
Baocao A5 - Graphics2d
ĐỒ ÁN MÔN HỌC
ĐỒ HỌA MÁY TÍNH
JAVA GRAPHIC 2D
MỤC LỤC
Đề mục Trang
Trang bìa
MỤC LỤC.......................................................................................................................... 2
LỜI MỞ ĐẦU....................................................................................................................3
CHƯƠNG 1. GIỚI THIỆU VỀ GRAPHICS 2D TRONG JAVA.......................................4
1.1. Định nghĩa về graphics 2D..................................................................................4
1.2. Thao tác..............................................................................................................4
1.3. Hình ảnh hai mô hình..........................................................................................4
CHƯƠNG 2. GIỚI THIỆU VỀ SHAPES TRONG JAVA.................................................5
2.1. Định nghĩa về shapes trong java.........................................................................5
2.2. Gói Java java.awt.geom......................................................................................5
2.3. Lớp Line 2D........................................................................................................6
2.4. Lớp Point2D.......................................................................................................6
2.5. Các lớp khác của java.awt.geom.........................................................................7
2.6. Lớp Path2D.........................................................................................................8
2.7. Thêm hình img trong java...................................................................................9
CHƯƠNG 3. GIỚI THIỆU VỀ STROKE AND FILL.....................................................10
3.1. Định nghĩa........................................................................................................10
3.2. BasicStroke.......................................................................................................11
CHƯƠNG 4. GIỚI THIỆU VỀ TRANSFORMS.............................................................12
4.1. Định nghĩa:.......................................................................................................12
CHƯƠNG 5. GIỚI THIỆU VỀ BUFFEREDIMAGE AND PIXEL.................................15
5.1. Định nghĩa........................................................................................................15
CHƯƠNG 6. DEMO........................................................................................................18
6.1. java2d/GraphicsStarter.java..............................................................................18
6.2. java2d/AnimationStarter.java............................................................................19
6.3. java2d/EventsStarter.java..................................................................................19
6.4. java2d/PaintDemo.java.....................................................................................20
6.5. java2d/JavaPixelManipulation.java...................................................................20
CHƯƠNG 7. KẾT LUẬN RÚT RA.................................................................................20
CHƯƠNG 8. PHÂN CÔNG CÔNG VIỆC VÀ TÀI LIỆU THAM KHẢO......................21
3
4
LỜI MỞ ĐẦU
Theo xu hướng của thời đại cộng nghệ 4.0 hiện nay, ngành công nghệ
thông tin là một trong những ngành hết sức quan trọng trên con đường hội
nhập và phát triển. Sản phẩm công nghệ hiện nay càng chịu sự đánh giá khắc khe
hơn từ phía những người dùng, đặc biệt là về sản phầm đồ họa được nhận rất nhiều sự
đánh giá từ những người dùng.
Xuất phát từ những lý do trên, cùng với sự hướng dẫn của cô Nguyễn Thị Anh
Thư, chúng em thực hiện nghiên cứu về graphics 2D để vận dụng những kiến thức đã
tự tìm hiểu từ những nguồn tài nguyên có sẵn, xây dựng một tự Games giải trí.
Do chưa có nhiều kinh nghiệm thực tiễn, nên đề tài thực hiện của em còn nhiều
thiếu sót, em mong nhận được sự đánh giá và nhận xét của thầy để đề tài được hoàn
thiện hơn.
Java là một ngôn ngữ hướng đối tượng. API của nó được định nghĩa là một tập
hợp lớn các lớp, Thực tế các thao tác vẽ trong API đồ họa ban đầu hầu hết được chứa
trong lớp có tên Đồ họa. Trong API mới hơn, các thao tác vẽ là các phương thức trong
một lớp có tên Graphics2D, là một lớp con của Đồ họa, do đó tất cả các hoạt động vẽ
ban đầu vẫn có sẵn.
Tất cả các vẽ nên được thực hiện bên trong paintComponent (); khi cần thay đổi
nội dung của bản vẽ, bạn có thể gọi phương thức Bảng điều khiển repaint () để kích
hoạt lệnh gọi paintComponent ().
Kiểu double có thể biểu thị một phạm vi số lớn hơn số float, với số chữ số có
nghĩa lớn hơn và gấp đôi là loại được sử dụng phổ biến hơn. Trong thực tế, giá trị
double đơn giản là dễ sử dụng hơn trong Java.
Kiểu float thường có đủ độ chính xác cho các ứng dụng đồ họa và chúng có lợi
thế là chiếm ít không gian hơn trong bộ nhớ. Hơn nữa, phần cứng đồ họa máy tính
thường sử dụng giá trị float bên trong.
Từ những kiểu trên, gói java.awt.geom thực sự cung cấp hai phiên bản của mỗi
hình dạng, một sử dụng tọa độ của kiểu float và một sử dụng tọa độ của kiểu double.
2.3. Lớp Line 2D
Line2D là một lớp trừu tượng. Nó có hai lớp con, một lớp biểu thị các dòng sử
dụng tọa độ float và một lớp sử dụng tọa độ kép.
Phần kỳ lạ nhất là các lớp con này được định nghĩa là các lớp lồng nhau bên
trong Line2D: Line2D.Float và Line2D.Double. Điều này có nghĩa là bạn có thể khai
báo một biến loại Line2D, nhưng để tạo một đối tượng, bạn cần sử dụng
Line2D.Double hoặc Line2D.Float:
Line2D line1, line2;
line1 = new Line2D.Double(1,2,5,7); // Line from (1.0,2.0) to (5.0,7.0)
line2 = new Line2D.Float(2.7F,3.1F,1.5F,7.1F); // (2.7,3.1) to (1.5,7.1)
Lưu ý rằng khi sử dụng các hằng số kiểu float trong Java, bạn phải thêm “F”
làm hậu tố cho giá trị. Đây là một lý do tại sao Double dễ dàng hơn trong Java. Để đơn
giản, bạn có thể muốn sử dụng Line2D.Double. Tuy nhiên, Line2D.Float có thể cho
hiệu suất tốt hơn một chút.
2.4. Lớp Point2D
Lớp trừu tượng Point2D, với các lớp con cụ thể Point2D.Double và
Point2D.Float, biểu thị một điểm theo hai chiều, được chỉ định bởi hai tọa độ số thực.
Một điểm không phải là hình dạng; bạn không thể điền vào hoặc thay đổi nó. Một
điểm có thể được xây dựng từ hai số thực:
new Point2D.Double(1.2,3.7).
8
Nếu p là biến loại Point2D, bạn có thể sử dụng p.getX () và p.getY () để truy
xuất tọa độ của nó và bạn có thể sử dụng p.setX (x), p.setY (y) hoặc p.setLocation (x,
y) để đặt tọa độ của nó.
Nếu pd là một biến loại Point2D.Double, bạn cũng có thể tham chiếu trực tiếp
đến tọa độ là pd.x và pd.y (và tương tự cho Point2D.Float). Các lớp khác trong
java.awt.geom cung cấp nhiều cách tương tự để thao túng các thuộc tính của chúng và
tôi đã thắng cố gắng liệt kê tất cả chúng ở đây.
2.5. Các lớp khác của java.awt.geom
Có một loạt các lớp đại diện cho các hình dạng hình học, bao gồm Line2D,
Oval2D, RoundRonymous2D, Ellipse2D, Arc2D và Path2D. Tất cả đều là các lớp trừu
tượng và mỗi lớp chứa một cặp các lớp con, chẳng hạn như Rectangle2D.Double and
Rectangle2D.Float.
Một số hình dạng, chẳng hạn như hình chữ nhật, có nội thất có thể được lấp
đầy; hình dạng như vậy cũng có những phác thảo có thể được xây dựng. Một số hình
dạng, chẳng hạn như đường, hoàn toàn là một chiều và chỉ có thể được xây dựng. Bên
cạnh các dòng, hình chữ nhật có lẽ là hình dạng đơn giản nhất.
Rectangle2D có một điểm góc (x, y), chiều rộng và chiều cao và có thể được
xây dựng từ dữ liệu đó.
new Rectangle2D.Double(x,y,w,h)
Điểm góc (x, y) chỉ định giá trị x - và y tối thiểu trong hình chữ nhật. Đối với hệ
tọa độ pixel thông thường, (x, y) là góc trên bên trái. Tuy nhiên, trong một hệ tọa độ
trong đó giá trị tối thiểu của y nằm ở dưới cùng, (x, y) sẽ là góc dưới bên trái. Các
Một biến r có kiểu Rectangle2D.Double có các biến thể hiện công khai r.x, r.y,
r.width, và r.height. Nếu chiều rộng hoặc chiều cao nhỏ hơn hoặc bằng 0, sẽ không có
gì được vẽ khi hình chữ nhật được lấp đầy hoặc xây dựng. Một nhiệm vụ phổ biến là
xác định một hình chữ nhật từ hai điểm góc (x1, y1) và (x2, y2).
Điều này có thể được thực hiện bằng cách tạo một hình chữ nhật có chiều cao
và chiều rộng bằng 0 và sau đó thêm điểm thứ hai vào hình chữ nhật.
Thêm một điểm vào hình chữ nhật làm cho hình chữ nhật phát triển vừa đủ để
bao gồm điểm đó:
9
Điều này thêm một đoạn đường cong bắt đầu tại vị trí bút hiện tại và kết thúc tại
(x, y), sử dụng (cx1, cy1) và (cx2, cy2) làm hai điểm kiểm soát cho đường cong.
Phương pháp để thêm một đoạn đường cong Bezier bậc hai vào một đường dẫn
là quadTo. Nó chỉ yêu cầu một điểm kiểm soát duy nhất:
p.quadTo( cx, cy, x, y );
Khi một đường tự giao nhau, phần bên trong của nó được xác định bằng cách
nhìn vào số quanh co. Có hai quy tắc có thể để xác định xem một điểm có phải là bên
trong hay không: hỏi xem số quanh co của đường cong về điểm đó có khác không hay
không, hoặc hỏi xem nó có phải là số chẵn hay không.
Có thể đặt quy tắc quanh co được sử dụng bởi Path2D p với
p.setWindingRule( Path2D.WIND NON ZERO );
p.setWindingrule( Path2D.WIND EVEN ODD );
Mặc định là WIND_NON_ZERO.
2.7. Thêm hình img trong java
Cuối cùng, có lưu ý rằng có thể vẽ một bản sao của hình ảnh vào bối cảnh đồ
họa. Hình ảnh có thể được tải từ một tập tin hoặc được tạo bởi chương trình. Tôi thảo
luận về khả năng thứ hai sau trong phần này. Một hình ảnh được đại diện bởi một đối
tượng của loại hình ảnh.
Trong thực tế, giả sử ở đây rằng đối tượng thuộc kiểu BufferedImage, là một
lớp con của Image. Nếu img là một đối tượng như vậy, thì :
g2.drawImage( img, x, y, null );
Nó sẽ vẽ hình ảnh với góc trên bên trái của nó tại điểm (x, y). (Tham số thứ tư
khó giải thích, nhưng nên được chỉ định là null cho BufferedImages.) Điều này vẽ hình
ảnh ở chiều rộng và chiều cao tự nhiên của nó, nhưng có thể chỉ định chiều rộng và
chiều cao khác nhau trong phương thức:
g2.drawImage( img, x, y, width, height, null );
Ngoài ra còn có một phương pháp để vẽ một chuỗi văn bản. Phương thức chỉ
định chuỗi và cơ sở của chuỗi. (Basepoint là góc dưới bên trái của chuỗi, bỏ qua các
“phần thụt” như đuôi trên chữ “g” (Ý chỗ này là nó sẽ bỏ qua cái dấu móc xuống của
chữ g ý , kiểu v ). Ví dụ:
11
Công cụ "pen" thường dùng để khoanh vùng những cái shape có định dạng
3.2. BasicStroke
Mặc định của Stroke là đường thẳng có độ rộng bằng 1.
Và được tính trong tọa độ đang dùng chứ không phải là 1 pixel.
Để vẽ đường thẳng có độ rộng khác có thể cài đặt lại bằng cú pháp:
Ví dụ: g2.setStroke ( new BasicStroke ( width ) )
Biến (width) là dạng float. Và cũng có thể giới hạn biến để điều khiển shape
trong cái khoanh vùng tại điểm cuối của nó và nơi mà 2 đối tượng giao nhau.
Ví dụ: g2.setStroke ( new BasicStroke ( 5.OF, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL ) )
Stroke và fill ở đây có nghĩa là đặt màu cho những pixel cố định.
Trong java luật dùng để tô màu pixel là "paint".
Paint có thể là 1 màu đơn,1 gradients hoặc 1 bản màu.
Giống như những thứ khác trong java. Paint đc diễn tả là đối tượng, nếu paint là
đối tượng thì : g2.setPaint(paint) sẽ set paint dùng trong hàm g2 để giới hạn điều
hành việc vẽ, cho đến khi pain đc thay đổi (Và cũng có 2 phương pháp khác là
g2.setColor(c) chỉ hoạt động khi tô màu và tương tự là g2.setPaint(c).
Màu khối (solid color) đc diễn tả là 1 đối tượng dạng Color. Đc thể hiện bên
trong như là 1 RGBA color.
Màu mờ (làm mờ) được tạo thành toàn diện nhất bằng cú pháp: New
color(r,g,b). Trong đó, R,g,b là số nguyên từ 0 đến 255 thể hiện các màu đc hợp thành
từ đỏ, vàng và xanh dương. Để có được độ làm mờ phải thêm biến alpha.
New color(r,g,b,a). Trong đó a cũng là số nguyên từ 0~255.
Và cũng có hàm Color.getHSBcolor(h,s,b), để tạo 1 cái màu lấy từ HSB color
mode. Trong trường hợp màu nền, sự bão hòa, độ sáng của cái color đó có giá trị dạng
float. Và nó cũng diễn tả được màu được trộn từ nhiều màu như là color.WHITE ,
color.RED ,và color.YELLOW.
Ví du:
Ngoài màu khối. Java còn class GradientPaint để điên tả các đường gradient và
TexturePaint để diễn tả các bản màu.(Hình ảnh bản màu đc sử dụng giống như cách
13
trong 3d graphic đc gọi là texture). Trong những trường hợp này color đuợ nạp vào
pixel tùy thuộc vào tọa độ của pixel.
Để tạo TexturePaint, bạn cần phải có đối tượng bufferedImage để chỉ rõ hình
ảnh đó được dùng như là 1 bảng màu (patterns). Bạn sẽ thắc mắc là làm sao để tọa độ
của cái image đó được map và hiển thị lên tọa độ của màn hình.
Bằng cách chỉ định 1 hình chữ nhật trong đó giữ lại 1 bản copy của Image dùng
cú pháp sau:
New texturePaint ( image, rect).
Trong đó image là BufferedImage, Rect là Rectangle2D.
Bên ngoài hình chữ nhật đó image sẽ tiếp tục theo chiều ngang và chiều dọc.
GradientPaint dùng form:
New GradientPaint(x1,y1,color1,x2,y2,color2,cylic).
X1,x2,y1,y2 dạng float.
Color1,color2 dạng color. Cylic là Boolean. Gradient color sẽ thay đổi trên
đoạn thẳng từ điểm 1(x1,y1) đến điểm 2(x2,y2).
Màu sẽ là color 1 tại điểm cuối đầu tiền và color 2 tại điểm cuối thứ 2. Màu sẽ
không thay đổi trên đường thẳng vuông góc với đoạn được vẽ. Biến Boolean cylic
nói lên cái patterns có đc lập lại hay không.
• g2.translate (dx, dy) – dịch chuyển về điểm dx theo chiều ngang và dy theo
chiều dọc.
• g2.shear (sx, sy) –biến dạng theo chiều ngang sx và chiều dọc sy
Sự biến đổi trong Java được biểu diễn dưới dạng một đối tượng của lớp
AffineTransform. Ta có thể khởi tạo phép biến đổi affine với phương thức constructor.
AffineTransform trns = new AffineTransform(a,b,c,d,e,f);
Đối tượng trns sẽ biến đổi một điểm (x,y) thành điểm (x1, y1)
x1 = a*x + c*y + e
y1 = b*x + d*y + f;
Có thể áp dụng đối tượng trns này cho bối cảnh đồ họa g2 bằng cách gọi
g2.transform(trns)
Bối cảnh đồ họa g2 bao gồm biến đổi affine hiện tại, là thành phần của tất cả
các biến đổi đã được áp dụng. Các lệnh như g2.rotate và g2.transform tùy chỉnh biến
đổi hiện tại. Ta có thể lấy một bản sao của biến đổi hiện tại bằng cách gọi
g2.getTransform (), trả về một đối tượng AffineTransform. Ta có thể gán biến đổi hiện
tại bằng cách sử dụng g2.setTransform (trns). Điều này thay thế biến đổi hiện tại trong
g2 bằng trns AffineTransform. (Lưu ý rằng g2.setTransform (trns) khác với
g2.transform (trns); lệnh thứ thất dùng để thay thế biến đổi hiện tại trong g2, trong khi
lệnh thứ hai sửa đổi biến đổi hiện tại bằng cách kết hợp nó với trns.)
Các phương thức getTransform và setTransform có thể được sử dụng để triển
khai mô hình phân cấp.Mô hình này được nói đến trong Phần 2.4, là trước khi vẽ một
đối tượng, ta nên lưu lại biến đổi hiện tại. Sau khi vẽ đối tượng, khôi phục biến đổi đã
lưu. Bất kỳ biến đổi mô hình bổ sung nào được áp dụng trong khi vẽ đối tượng và các
đối tượng con của nó sẽ không có hiệu ứng bên ngoài đối tượng. Trong Java, nó trông
giống như:
AffineTransform savedTransform = g2.getTransform();
drawObject();
g2.setTransform( savedTransform );
Đối với đồ họa phân cấp, chúng ta thực sự cần một ngăn xếp biến đổi. Tuy
nhiên, nếu hệ thống phân cấp được triển khai bằng chương trình con, thì đoạn mã trên
15
sẽ là một phần của chương trình con và giá trị của biến cục bộ đã lưu biến đổi sẽ được
lưu trữ trên ngăn xếp chương trình con. Thực tế, chúng ta sẽ sử dụng ngăn xếp chương
trình con để thực hiện ngăn xếp các biến đổi đã lưu.
Ngoài các phép biến đổi mô hình, các biến đổi được sử dụng để gán vào phép
biến đổi window-to-viewport để thiết lập hệ tọa độ và sẽ được sử dụng để vẽ. Điều này
thường được thực hiện trong Java ngay sau khi bối cảnh đồ họa được tạo, trước bất kỳ
thao tác vẽ nào. Nó có thể được thực hiện với phiên bản Java của hàm
applyWindowToViewportTransformation từ Tiểu mục 2.3.7. Xem chương trình mẫu
“java2d / GraphicsStarter.java” là 1 ví dụ.
Tôi sẽ đề cập thêm một lần sử dụng cho các đối tượng AffineTransform: Đôi
khi, bạn cần phải chuyển đổi rõ ràng tọa độ. Ví dụ, tọa độ đối tượng đã cho (x, y), tôi
có thể cần biết chúng thực sự sẽ ở đâu trên màn hình, theo tọa độ pixel. Đó là, tôi
muốn chuyển đổi (x, y) bằng biến đổi hiện tại để có tọa độ pixel tương ứng. Lớp
AffineTransform có một phương thức để áp dụng phép biến đổi affine cho một điểm.
Nó hoạt động với các đối tượng thuộc dạng Point2D. Đây là một ví dụ:
AffineTransform trns = g2.getTransform();
Point2D.Double originalPoint = new Point2D.Double(x,y);
Point2D.Double transformedPoint = new Point2D.Double();
trns.transform( originalPoint, transformedPoint );
// transformedPoint hiện chứa các chuỗi pixel tương ứng với (x,y)
int pixelX = (int)transformedPoint.x;
int pixelY = (int)transformedPoint.y;
Có 1 điều tôi đã từng sử dụng là khi làm việc với chuỗi. Thông thường khi hiển
thị một chuỗi trong một hệ tọa độ được chuyển đổi, tôi muốn chuyển đổi cơ sở của
một chuỗi, nhưng không phải là chính chuỗi đó. Đó là tôi muốn chuyển tác động đến
vị trí của chuỗi nhưng không phải kích thước hoặc xoay. Để thực hiện điều này, tôi sử
dụng kỹ thuật trên để lấy tọa độ pixel cho điểm gốc được chuyển đổi, sau đó vẽ chuỗi
ở các tọa độ đó, sử dụng một bản gốc,bối cảnh đồ họa chưa được dịch.
Các hoạt động đảo ngược đôi khi cũng cần thiết. Nghĩa là, tọa độ pixel đã cho
(px, py), tìm điểm (x, y) được chuyển thành (px, py) bằng một phép biến đổi affine đã
16
cho. Ví dụ: khi thực hiện tương tác chuột, bạn thường sẽ biết tọa độ pixel của chuột,
nhưng bạn sẽ muốn tìm điểm tương ứng trong hệ tọa độ đã chọn của riêng bạn. Đối
với điều đó, bạn cần một biến đổi nghịch đảo. Nghịch đảo của một biến đổi affine T là
một biến đổi khác tương ứng với biến đổi ngược lại. Nghĩa là, nếu T (x, y) = (px, py)
và nếu R là biến đổi nghịch đảo thì R (px, py) = (x, y). Trong Java, có thể thu được
biến đổi nghịch đảo của một trns AffineTransform
(Lưu ý cuối cùng: Các phương thức vẽ cũ trước đó của đồ họa, như drawLine,
sẽ sử dụng tọa độ nguyên. Điều quan trọng cần lưu ý là bất kỳ hình dạng nào được vẽ
bằng các phương thức cũ này đều phải chịu sự biến đổi giống như các hình dạng như
Line2D được chỉ định với tọa độ số thực. Ví dụ: vẽ một dòng bằng g.drawLine
(1,2,5,7) sẽ có tác dụng tương tự như vẽ Line2D có điểm cuối (1.0,2.0) và (5.0,7.0).
Trong thực tế, tất cả các bản vẽ bị ảnh hưởng bởi sự chuyển đổi tọa độ.)
nơi bạn có thể vẽ, giống hệt như cách bạn vẽ lên màn hình. Nghĩa là, bạn có thể có
được bối cảnh đồ họa g2 thuộc loại Grapics2D mà bạn có thể sử dụng để vẽ trên màn
hình.
BufferedImage là một hình ảnh và bạn có thể vẽ nó lên màn hình, hoặc vào bối
cảnh đồ họa nào khác giống như bất ký hình ảnh nào khác, nghĩa là bằng cách sử dụng
phương thức drawImage của bồi cảnh đồ họa mà bạn muốn hiển thị hình ảnh. Trong
một thiết lập điển hình có các biến:
Buffered OSC; (canvas ngoài màn hình)
Graphics2D OSG; (bối cảnh đồ họa để vẽ lên khung)
Hàm tạo cho BufferedImage chỉ định chiều rộng và chiều cao của hình ảnh
cùng với loại của nó. Kiểu này cho biết màu sắc nào có thể được hiển thị trong hình
ảnh và cách chúng được lưu trữ. Ở đây là TYPE INT RGB, có nghĩa là hình ảnh sử
dụng màu RGB thông thường với 8bit cho mỗi thành phần màu. Ba thành phần màu
cho một pixel được đóng gói thành một số nguyên duy nhất giá trị.
Trong một chương trình sử dụng BufferedImage để lưu trữ một bản sao của
hình ảnh trên màn hình, phương thức paintComponent thường có dạng:
protected void paintComponent(Graphics g) {
g.drawimage( OSC, 0, 0, null );
Graphics2D g2 = (Graphics2D)g.create();
.
. // Draw extra stuff on top of the image.
}
Một chương trình mẫu sử dụng kỹ thuật này là
java2dJavaPixelManipulation.java. Trong đó chương trình, người dùng có thể vẽ các
đường, hình chữ nhật và hình bầu dục bằng cách kéo chuột. Như con chuột di chuyển,
hình dạng được vẽ giữa điểm bắt đầu của chuột và vị trí hiện tại của nó. Như chuột di
18
chuyển, các phần của hình ảnh hiện tại có thể được che lại và phát hiện ra mà không
cần thay đổi hình ảnh hiện có. Trên thực tế, hình ảnh nằm trong một khung vẽ ngoài
màn hình và hình dạng người dùng đang vẽ thực sự được vẽ bởi paintComponent trên
nội dung của khung vẽ. Các hình dạng không được vẽ vào hình ảnh chính thức trong
khung vẽ cho đến khi người dùng nhả chuột và kết thúc
các hoạt động kéo.
Nhưng lý do chính của tôi để viết chương trình là để minh họa thao tác pixel,
nghĩa là tính toán với các thành phần màu của các pixel riêng lẻ. Lớp BufferedImage
có các phương thức để đọc và thiết lập màu của từng pixel. Một hình ảnh bao gồm các
hàng và cột pixel. Nếu OSC là BufferedImage, thì:
int color = OSC.getRGB(x,y)
Lấy số nguyên biểu thị màu của pixel trong số cột x và số hàng y. Mỗi thành
phần màu được lưu trữ trong trường 8 bit trong giá trị màu nguyên. Các màu riêng biệt
các thành phần có thể được trích xuất để xử lý bằng các toán tử thao tác bit Java:
int red = (color >> 16) & 255;
int green = (color >> 8) & 255;
int blue = color & 255;
Tương tự, với các giá trị thành phần màu đỏ, lục và lam trong phạm vi 0 đến
255, chúng ta có thể kết hợp các giá trị thành phần đó thành một số nguyên duy nhất
và sử dụng nó để đặt màu của pixel trong bức hình:
int color = (red << 16) | (green << 8) | blue;
OSC.setRGB(x,y,color);
Ngoài ra còn có các phương pháp để đọc và thiết lập màu sắc của toàn bộ khu
vực hình chữ nhật của pixel. Các thao tác pixel được sử dụng để thực hiện hai tính
năng của chương trình mẫu. Đầu tiên, có một công cụ Smudge. Khi người dùng kéo
bằng công cụ này, nó giống như bôi sơn ướt. Khi mà người dùng nhấp chuột lần đầu
tiên, các thành phần màu từ một hình vuông pixel nhỏ xung quanh vị trí chuột được
sao chép vào mảng. Khi người dùng di chuyển chuột, màu sắc từ các mảng là pha trộn
với màu của các pixel gần vị trí chuột. Đây là một hình chữ nhật nhỏ đã “smudged”.
19
Việc sử dụng thứ hai của thao tác pixel là trong việc triển khai các bộ lọc của
Cameron. Bộ lọc, trong chương trình này, là một thao tác sửa đổi hình ảnh bằng cách
thay thế màu của từng pixel bằng trung bình trọng số của các màu của hình vuông 3
nhân 3 pixel. Ví dụ, bộ lọc Blur Blur, sử dụng các trọng số bằng nhau cho tất cả các
pixel ở mức trung bình, do đó màu của pixel được thay đổi thành trung bình đơn giản
của các màu của pixel đó và các lân cận của nó. Sử dụng các trọng lượng khác nhau
cho mỗi pixel có thể tạo ra một số điểm nổi bật tác dụng.
Thao tác pixel trong chương trình mẫu tạo ra các hiệu ứng có thể đạt được với
đồ họa vector thuần túy. Tôi khuyến khích bạn tìm hiểu thêm bằng cách xem mã
nguồn. Bạn cũng có thể xem các bản demo trực tiếp trong phần tiếp theo, phần thực
hiện các hiệu ứng tương tự bằng đồ họa canvas HTML.
CHƯƠNG 6. DEMO
6.1. java2d/GraphicsStarter.java
20
6.2. java2d/AnimationStarter.java
6.3. java2d/EventsStarter.java
21
6.4. java2d/PaintDemo.java
6.5. java2d/JavaPixelManipulation.java