Vui lòng đọc tất cả bài trước đó trong tutorial Ma trận LED thì các bạn mới hiểu bài này
Trong mô hình màu RGB, người ta thường thêm vào các đối tượng hiển thị 1 thông số mô tả độ trong suốt của đối tượng đó khi hiển thị lên màn hình. Thông số này được gọi là kênh Alpha, mô hình màu đầy đủ là ARGB
Kênh alpha không thực sự quan trong lắm nhưng nó sẽ làm ứng dụng của bạn trở nên đẹp và chân thực hơn nhiều. Trong suốt tutorial, chúng ta đã quá quen với hàm cơ bản set_pixel có nhiệm vụ vẽ 1 pixel lên màn hình, bây giờ mình sẽ viết thêm 1 hàm nữa gọi là add_pixel, hàm này có nhiệm vụ tương tự như hàm set_pixel nhưng nó sẽ nhận thêm thông số kênh alpha vào nữa
Công thức để thêm 1 pixel mới với độ trong suốt của nó như sau:
pixel = (pixel_mới * A_pixel_mới)/255 + ((255- A_pixel_mới) * pixel_cũ)/255
Trong đó:
- pixel_mới là giá trì màu của pixel bạn muốn add vào
- A_pixel_mới là độ trong suốt của pixel bạn muốn add vào
- pixel_cũ là pixel đã có sẵn trước đó
Ví dụ
Thông thường khi in chữ lên 1 tấm ảnh nền, người ta hay có 1 lớp phủ mờ ở dưới để nhìn chữ rõ hơn
Các bạn có thể thấy 1 lớp phủ mờ sẽ giúp ảnh nền phía dưới không hoàn toàn bị che đi mà vẫn làm nổi bật phần chữ
Trong thư viện VNfontmake mình tạo thêm hàm put_String_noBackColor để in chữ ra màn hình mà không in các pixel nền. Các bạn có thể tải lại source cho thư viện này tại đây
Mình sẽ thêm vào file main.c hàm add_pixel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void add_px(int16_t x, int16_t y,Color my_color,uint8_t opacity) { if(x < 0) return; if(y < 0) return; if(x > P5_W) return; if(y > P5_H) return; if(opacity) { uint16_t locarion_r = 0*arrD1 + y*arrD2 + x; uint16_t locarion_g = 1*arrD1 + y*arrD2 + x; uint16_t locarion_b = 2*arrD1 + y*arrD2 + x; uint8_t oneminusalpha = 255 - opacity; Buffer_RGB[locarion_r] = (my_color.r * opacity)/255 + (oneminusalpha * Buffer_RGB[locarion_r])/255; Buffer_RGB[locarion_g] = (my_color.g * opacity)/255 + (oneminusalpha * Buffer_RGB[locarion_g])/255; Buffer_RGB[locarion_b] = (my_color.b * opacity)/255 + (oneminusalpha * Buffer_RGB[locarion_b])/255; } } |
Thuộc tính alpha ở đây mình sẽ đặt thành opacity (mức độ trong suốt) nó sẽ có giá trị tương ứng với giá trị tối đa của các thành phần màu r,g,b. Do code mình đang sử dụng 8bit màu cho mỗi thành phần nên opacity sẽ có giá trị từ 0 đến 255
Và viết thêm 1 hàm vẽ hình vuông với các thông số x,y.width,height,color,opacity
1 2 3 4 5 6 |
void draw_rec(int16_t x,int16_t y,uint16_t w,uint16_t h,Color my_color,uint8_t opacity) { for(int i=0;i<w;i++) for(int k=0;k<h;k++) add_px(x+i,y+k,my_color,opacity); } |
Bây giờ mình sẽ tiến hành vẽ lớp phủ mờ và chữ ra, mình sẽ vẽ 1 lớp phủ có giá trị trong suốt = 200/255
1 2 |
draw_rec(0,0,45,10,BLACK,200); put_String_noBackColor(0,0,"Xin chào",Font1,GREEN); |
Thậm chí các chữ cái màu trắng vẫn rất nổi bật dù nền phía dưới của nó là màu trắng
Còn khi không sử dụng lớp phủ mờ này thì dòng chữ “Xin chào” rất khó để nhìn
Tải toàn bộ project tại đây