Các thuật toán để đổ màu rất đơn giản:
- Bắt đầu với bất kỳ điểm ảnh trong hình dạng để được lấp đầy.
- Nhớ màu sắc của điểm ảnh này, đặt tên là initialColor.
- Thêm điểm ban đầu vào danh sách kiểm tra
- Cho tất cả các điểm P trong danh sách kiểm tra làm
+ Nếu P.color = initialColor sau đó
+ Điền vào điểm P với màu sắc mục tiêu
+ Thêm tất cả các điểm lân cận của điểm P vào danh sách kiểm tra
// Code Java
package animationfiller;
/******************************************************************************
* File : AnimationFiller.java
* Author : http://lap-trinh-may-tinh.blogspot.com/
* Description :
* Demonstrate a flood fill algorithm.
* Tested with : JDK 1.6
******************************************************************************/
import java.awt.image.BufferedImage;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.Point;
class AnimationFiller
{
// fill the whole image with a color specified by its RGB component
static void fillImage(BufferedImage image, int red, int green, int blue)
{
int packedRGB = (red*256+green)*256+blue;
for (int y=0;y<image.getHeight(null);y++)
{
for (int x=0;x<image.getWidth(null);x++)
image.setRGB(x,y,packedRGB);
}
}
// draw a red circle with a pen width of 5 pixels
static void drawCircle(BufferedImage image)
{
java.awt.Graphics2D gr=(java.awt.Graphics2D) image.getGraphics();
gr.setColor(new java.awt.Color(255,0,0)); // red
gr.setStroke(new java.awt.BasicStroke(5)); // set pen width to 5 pixel
gr.drawArc(5,5,150,150,0,360); // (x,y,w,h,startDegree, endDegree);
}
// repaint the image and delay for a little while
private static void repaintAndDelay(BufferedImage image)
{
_imageLabel.setIcon(new ImageIcon(image));
_imageLabel.repaint();
try { Thread.sleep(1); } catch (Exception ignore) {}
}
// implements the flood fill algorithm
public static void floodFill(BufferedImage image, int x,int y, int fillColor)
{
java.util.ArrayList<Point> examList=new java.util.ArrayList<Point>();
int initialColor=image.getRGB(x,y);
examList.add(new Point(x,y));
while (examList.size()>0)
{
Point p = examList.remove(0); // get and remove the first point in the list
if (image.getRGB(p.x,p.y)==initialColor)
{
x = p.x; y = p.y;
image.setRGB(x, y, fillColor); // fill current pixel
examList.add(new Point(x-1,y)); // check west neighbor
examList.add(new Point(x+1,y)); // check east neighbor
examList.add(new Point(x,y-1)); // check north neighbor
examList.add(new Point(x,y+1)); // check south neighbor
repaintAndDelay(image); // this line can be removed
}
}
}
public static int packRgb(int r,int g,int b)
{
return (r*256+g)*256+b;
}
static JLabel _imageLabel;
public static void main(String[] args) throws Exception
{
// create an 200x200 RGB image
BufferedImage image=new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
// fill the image with green color
fillImage(image,0,255,0);
// draw a red circle with 5 pixel pen width
drawCircle(image);
JLabel imageLabel=new JLabel();
_imageLabel = imageLabel; // make it global
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Filling the circle with yellow color ...");
javax.swing.JFrame window=new javax.swing.JFrame();
window.setTitle("Macteki flood filler");
window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
window.add(imageLabel);
window.pack();
window.setVisible(true);
// fill the circle with yellow color
int yellow = packRgb(255,255,0);
int x=50, y=50; // make sure (x,y) is within the circle
floodFill(image,x,y, yellow);
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Completed !");
}
}
- Bắt đầu với bất kỳ điểm ảnh trong hình dạng để được lấp đầy.
- Nhớ màu sắc của điểm ảnh này, đặt tên là initialColor.
- Thêm điểm ban đầu vào danh sách kiểm tra
- Cho tất cả các điểm P trong danh sách kiểm tra làm
+ Nếu P.color = initialColor sau đó
+ Điền vào điểm P với màu sắc mục tiêu
+ Thêm tất cả các điểm lân cận của điểm P vào danh sách kiểm tra
// Code Java
package animationfiller;
/******************************************************************************
* File : AnimationFiller.java
* Author : http://lap-trinh-may-tinh.blogspot.com/
* Description :
* Demonstrate a flood fill algorithm.
* Tested with : JDK 1.6
******************************************************************************/
import java.awt.image.BufferedImage;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.Point;
class AnimationFiller
{
// fill the whole image with a color specified by its RGB component
static void fillImage(BufferedImage image, int red, int green, int blue)
{
int packedRGB = (red*256+green)*256+blue;
for (int y=0;y<image.getHeight(null);y++)
{
for (int x=0;x<image.getWidth(null);x++)
image.setRGB(x,y,packedRGB);
}
}
// draw a red circle with a pen width of 5 pixels
static void drawCircle(BufferedImage image)
{
java.awt.Graphics2D gr=(java.awt.Graphics2D) image.getGraphics();
gr.setColor(new java.awt.Color(255,0,0)); // red
gr.setStroke(new java.awt.BasicStroke(5)); // set pen width to 5 pixel
gr.drawArc(5,5,150,150,0,360); // (x,y,w,h,startDegree, endDegree);
}
// repaint the image and delay for a little while
private static void repaintAndDelay(BufferedImage image)
{
_imageLabel.setIcon(new ImageIcon(image));
_imageLabel.repaint();
try { Thread.sleep(1); } catch (Exception ignore) {}
}
// implements the flood fill algorithm
public static void floodFill(BufferedImage image, int x,int y, int fillColor)
{
java.util.ArrayList<Point> examList=new java.util.ArrayList<Point>();
int initialColor=image.getRGB(x,y);
examList.add(new Point(x,y));
while (examList.size()>0)
{
Point p = examList.remove(0); // get and remove the first point in the list
if (image.getRGB(p.x,p.y)==initialColor)
{
x = p.x; y = p.y;
image.setRGB(x, y, fillColor); // fill current pixel
examList.add(new Point(x-1,y)); // check west neighbor
examList.add(new Point(x+1,y)); // check east neighbor
examList.add(new Point(x,y-1)); // check north neighbor
examList.add(new Point(x,y+1)); // check south neighbor
repaintAndDelay(image); // this line can be removed
}
}
}
public static int packRgb(int r,int g,int b)
{
return (r*256+g)*256+b;
}
static JLabel _imageLabel;
public static void main(String[] args) throws Exception
{
// create an 200x200 RGB image
BufferedImage image=new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
// fill the image with green color
fillImage(image,0,255,0);
// draw a red circle with 5 pixel pen width
drawCircle(image);
JLabel imageLabel=new JLabel();
_imageLabel = imageLabel; // make it global
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Filling the circle with yellow color ...");
javax.swing.JFrame window=new javax.swing.JFrame();
window.setTitle("Macteki flood filler");
window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
window.add(imageLabel);
window.pack();
window.setVisible(true);
// fill the circle with yellow color
int yellow = packRgb(255,255,0);
int x=50, y=50; // make sure (x,y) is within the circle
floodFill(image,x,y, yellow);
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Completed !");
}
}
Một số tài liệu và khoá học bổ ích dành cho bạn:
# Tài liệu: Lập trình hướng đối tượng JAVA core dành cho người mới bắt đầu học lập trình [Click để xem]
# Khoá học online: Lập trình Java trong 4 tuần [Click để xem]