5.7. Hợp thành ảnh

Các phép vẽ hình học ở trang trước ghi các dấu hình học lên ảnh -- đường thẳng, hình chữ nhật, đoạn văn bản. Điều đó bao phủ hầu hết các chú thích mà thuật toán cần hiển thị, nhưng không phải tất cả. Đôi khi chú thích bản thân là một ảnh: một khung hình tham chiếu đã chụp để hiển thị cạnh nhau với khung hình hiện tại, một ảnh thu nhỏ của lần chụp trước được hiển thị ở góc của bản xem trước, một mẫu đã lưu trước đó được hiển thị chồng lên khung hình trực tiếp để hiệu chỉnh. Cơ chế để vẽ một ảnh lên ảnh khác là một phương thức duy nhất -- draw_image() -- với đủ tham số để xử lý vị trí, tỷ lệ, bảng màu và độ trong suốt mà quá trình hợp thành thực sự cần.

5.7.1. Lệnh gọi cơ bản

Ở dạng đơn giản nhất, draw_image nhận một Image khác và vị trí để vẽ nó:

reference = image.Image("/sdcard/reference.bmp")
img.draw_image(reference, x=10, y=10)

Đích là img; nguồn là reference; điểm ảnh góc trên bên trái của nguồn được đặt tại (10, 10) của img, và phần còn lại của các điểm ảnh nguồn tiếp tục sang phải và xuống dưới từ đó. Các điểm ảnh của đích mà nguồn phủ lên sẽ bị ghi đè bằng các điểm ảnh tương ứng của nguồn; các điểm ảnh ngoài vùng phủ của nguồn được giữ nguyên.

Nếu nguồn vượt ra ngoài cạnh của đích, các phần lọt ra ngoài sẽ bị cắt bỏ một cách im lặng -- cùng hành vi linh hoạt mà set_pixel thể hiện với các vị trí ngoài phạm vi. Mã ứng dụng không cần phải giới hạn vị trí vào kích thước ảnh trước; nó có thể truyền vị trí mong muốn và để phương thức xử lý việc cắt bỏ.

5.7.2. Tải tệp trực tiếp

draw_image chấp nhận đường dẫn tệp thay cho đối số Image và tải tệp trước khi hợp thành:

img.draw_image("/sdcard/reference.bmp", x=10, y=10)

Điều đó trông như một tiện lợi -- một dòng thay vì hai -- và đúng vậy, nhưng sự khác biệt không chỉ là cú pháp. Xây dựng một Image từ tệp sẽ cấp phát một bộ đệm để lưu các điểm ảnh đã giải mã, và bộ đệm đó tồn tại cho đến khi bộ thu gom rác giải phóng nó. Truyền đường dẫn trực tiếp cho draw_image cho phép module giải mã tệp vào một bộ đệm tạm, hợp thành từ đó, và giải phóng bộ đệm khi lệnh gọi trả về, mà không cần mã ứng dụng phải giữ tham chiếu đến một Image riêng biệt giữa các khung hình.

5.7.3. Thay đổi tỷ lệ

Khi nguồn và đích có kích thước khác nhau -- một ảnh chụp độ phân giải thấp được hợp thành lên canvas độ phân giải cao hơn, hoặc một ảnh thu nhỏ cần được điều chỉnh thành một phần nhất định của khung hình -- hai tham số tỷ lệ đảm nhận việc thay đổi kích thước nguồn khi vẽ:

img.draw_image(reference, x=10, y=10, x_scale=2.0, y_scale=2.0)

x_scaley_scale là các số thực độc lập; truyền cả hai cùng giá trị sẽ thay đổi tỷ lệ đều, và truyền các giá trị khác nhau sẽ kéo dãn hoặc thu nhỏ nguồn theo một trục. Việc thay đổi tỷ lệ xảy ra tại thời điểm vẽ; reference nguồn không bị thay đổi.

Một bitmask gồm các cờ gợi ý quyết định cách thay đổi tỷ lệ thực sự nội suy giữa các điểm ảnh. image.BILINEAR tạo ra kết quả mượt mà hơn với chi phí tính toán nhiều hơn; image.BICUBIC tạo ra kết quả mượt mà hơn nữa và tốn kém hơn; giá trị mặc định sử dụng phép nội suy láng giềng gần nhất, đây là lựa chọn rẻ nhất và phù hợp khi nguồn đã ở độ phân giải điểm ảnh của đích. Các cờ xử lý tỷ lệ khung hình -- SCALE_ASPECT_KEEP, SCALE_ASPECT_EXPAND, SCALE_ASPECT_IGNORE -- quyết định phải làm gì khi tỷ lệ khung hình của nguồn không khớp với hình chữ nhật nó đang được vẽ vào.

5.7.4. Pha trộn alpha

Theo mặc định, draw_image thay thế các điểm ảnh đích bằng các điểm ảnh nguồn. Khi mục tiêu là lớp phủ mờ đục -- để đích hiển thị xuyên qua nguồn -- tham số alpha kiểm soát cách hai bên được pha trộn. alpha=0 chỉ hiển thị đích (không có nguồn); alpha=255 là giá trị mặc định và chỉ hiển thị nguồn (thay thế hoàn toàn); các giá trị trung gian pha trộn hai bên theo tỷ lệ:

img.draw_image(overlay, x=0, y=0, alpha=128)

Đối số riêng biệt alpha_palette là cơ chế alpha theo từng điểm ảnh duy nhất của module. Nó nhận một ảnh GRAYSCALE có các giá trị được sử dụng làm alpha tại vị trí tương ứng trong nguồn -- ví dụ như một bản đồ nhiệt có alpha thay đổi theo cường độ. Alpha phải được cung cấp dưới dạng đối số thang xám riêng biệt đó; một ảnh nguồn mang kênh alpha riêng của nó (ví dụ PNG có độ trong suốt) không tự động mang nó qua.

5.7.5. Vùng quan tâm (ROI) nguồn và bảng màu

Hai tham số bổ sung hoàn thiện cơ chế hợp thành:

  • roi=(x, y, w, h) giới hạn nguồn vào một hình chữ nhật con của nó, chỉ hình chữ nhật đó mới được hợp thành lên đích. Hữu ích để cắt xén ngay trong lệnh gọi, mà không cần chuẩn bị một trung gian đã cắt trước.

  • color_palette thay thế giá trị của từng điểm ảnh nguồn qua bảng tra cứu trước khi vẽ -- cùng cơ chế mà to_rainbow()to_ironbow() sử dụng, được trình bày ở đây để một lớp phủ có thể được áp bảng màu trên đường đến đích mà không cần một lần chuyển đổi riêng biệt.

Cả hai đều kết hợp với mọi thứ khác trong lệnh gọi: tỷ lệ, alpha, đối số mask phía đích, và tham số roi phía đích giới hạn ghi vào một hình chữ nhật của đích.