Trong bài này, tôi sẽ hướng dẫn cách tạo một hiệu ứng reflection cho một image.

Source code
1.Khai báo phương thức:
Ta bắt đầu khai báo phương thức sau:
public static Image createReflectedImage(Image image, int bgColor, int reflectionHeight)
{
}
Ở phương thức trên, ta thấy có 3 tham số:

  • image: image gốc được reflected.
  • bgColor: màu background của image.
  • reflectionHeight: chiều cao của hiệu ứng reflection.

2. Tạo image kiểu Mutable:
Bây giờ, ta tạo image mutable để nắm giữ kết quả reflection.
int w = image.getWidth();
int h = image.getHeight();
Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Chúng ta lưu trữ width và height vào 2 biến kiểu int, sau đó tạo image mutable cùng width, nhưng height bằng h(chiều cao image ban đầu) cộng với chiều cao được reflection.
3. Sao chép Image gốc:
Các bước vẽ được thực hiện theo các bước sau:
Graphics g = reflectedImage.getGraphics();
g.setColor(bgColor);
g.fillRect(0, 0, w, h + reflectionHeight);
g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);
4. Tạo hiệu ứng reflection:
Đây là phần quan trọng của bài báo này, đó là tạo hiệu ứng reflection cho image.

  • Đối với mỗi dòng ngang của image được reflection, đi theo tọa độ vertical tương ứng của image gốc.
  • Lấy dữ liệu của đường ngang tương ứng của image gốc.
  • Tính toán alpha để áp dụng vào dòng này, và áp dụng nó vào mỗi phần tử của mảng dữ liệu  RGB.
  • Vẽ mảng dữ liệu RGB vào image được reflection bằng cách sử dụng đối tượng Graphics.

Sau đây là mã nguồn:

int[] rgba = new int[w];
int currentY = -1; 
for(int i = 0; i < reflectionHeight; i++)
{ 
       int y = (h - 1) - (i * h / reflectionHeight);
        if(y != currentY)
           image.getRGB(rgba, 0, w, 0, y, w, 1);
        int alpha = 0xff - (i * 0xff / reflectionHeight);
        for(int j = 0; j < w; j++)
        {
               int origAlpha = (rgba[j] >> 24);
               int newAlpha = (alpha & origAlpha) * alpha / 0xff;
               rgba[j] = (rgba[j] & 0x00ffffff);
               rgba[j] = (rgba[j] | (newAlpha << 24));
        }
        g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}

Trong ví dụ trên, mảng rgba[] nắm giữ dữ liệu hàng điểm ảnh hiện thời, và sẽ được làm mới chỉ khi thực sự cần thiết(vì vậy khi tọa độ y của image gốc thay đổi).

code