Chụp màn hình OpenGL thành phim
OpenGL
1
Ruby
106
White

Ngoc Dao viết ngày 21/03/2016

Khi viết chương trình OpenGL xong, muốn chụp màn hình lại thành ảnh tĩnh ta đơn giản là chụp lại màn hình (ví dụ ấn PrintScreen trên Windows). Muốn chụp thành phim thường ta dùng chương trình đại loại như iShowU. Có cách khác là tự xuất ra ảnh ngay trong chương trình OpenGL của mình, rồi sau đấy ghép ảnh thành phim. Bài viết này sẽ cho thấy cách này đơn giản chỉ cần thêm vài dòng mã.

Qui trình

  1. Sau khi vẽ ra màn hình, trước khi swap buffer ta dùng hàm glReadPixels để chụp lại màn hình OpenGL ra mảng byte theo thứ tự màu RGB ứng với mỗi điểm ảnh.
  2. Ghi mảng byte này thành tập tin .ppm trên đĩa. Tập tin .ppm có 2 kiểu: plain text và binary, ta dùng kiểu binary. Định dạng .ppm này đơn giản, viết chục dòng là xuất được. Nếu muốn xuất theo định dạng .png, .jpg v.v. thì phải dùng thêm thư viện có thể sẽ hơi loằng ngoằng.
  3. Dùng chương trình ffmpeg để gom các tập tin .ppm thành phim.

Có thể xử lí cao cấp hơn là dùng thẳng thư viện encode video như libffmpeg để chuyển thẳng mảng byte thành phim. Trên Mac OS còn có thêm lựa chọn khác là có thể dùng thư viện QuickTime để chuyển thành phim .mov, có rất nhiều ví dụ ở developer.apple.com.

Ví dụ

Ta sẽ chụp màn hình của bài NeHe số 36 thành phim. Để đơn giản, ta dùng ruby-opengl, nó có sẵn bài này. Ta thêm vài dòng sau trước glutSwapBuffers:

  frame = glReadPixels(0, 0, 640, 480, GL_RGB, GL_UNSIGNED_BYTE)
@iframe = 0 unless @iframe
filename = sprintf('%03d.ppm', @iframe)
File.open(filename, 'wb') { |f| f.write("P6\n640 480\n255\n"); f.write(frame) }
print " "
@iframe += 1

Chạy chương trình để thu được các tập tin .ppm, rồi chạy lệnh:

ffmpeg -r 60 -qscale 1 -i %03d.ppm movie.avi

để thu được phim.

Có vài điểm cần cải tiến thêm, đây là bài tập nhỏ dành cho độc giả:

  • Nên tính toán chính xác frame rate thay vì chỉ định số 60 như trên. Hơn nữa mắt người chỉ cần khoảng 30 frame/giây là đủ, không cần ghi ra quá nhiều tập tin như trên.
  • Ảnh thu từ hàm glReadPixels bị lộn ngược theo hướng trên dưới, cần đảo lại.

Ghi chú cho OpenGL ES

OpenGL ES dùng cho thiết bị di động, như iPhone. OpenGL ES cũng có hàm glReadPixels, nhưng có thể không hoạt động với tham số GL_RGB như trong ví dụ trên. Khi chuyển thành GL_RGBA hoặc GL_BGRA thì có thể nó lại hoạt động tốt. Tất nhiên lúc này cần xử lí thêm để loại bỏ kênh A, đổi lại thành RGB trước khi ghi ra đĩa.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Ngoc Dao

102 bài viết.
252 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
56 6
Làm thế nào để nâng cấp trang web mà không làm gián đoạn dịch vụ? Đây là câu hỏi phỏng vấn các công ty lớn thường hỏi khi bạn xin vào vị trí làm lậ...
Ngoc Dao viết 2 năm trước
56 6
White
32 0
Bài viết này giải thích sự khác khác nhau giữa hai ngành khoa học máy tính (computer science) và kĩ thuật phần mềm (software engineering), hi vọng ...
Ngoc Dao viết gần 2 năm trước
32 0
White
28 1
Nếu là team leader, giám đốc công ty hay tướng chỉ huy quân đội, vấn đề cơ bản bạn gặp phải là “hướng mọi người đi theo con đường bạn chỉ ra”. Thử...
Ngoc Dao viết gần 2 năm trước
28 1
Bài viết liên quan
White
8 6
Chưa xem phần 2? Xem (Link) Trong bài viết này tôi giới thiệu cho các bạn về khái niệm function arity, một cách gọi mĩ miều của số lượng argument ...
Lơi Rệ viết hơn 2 năm trước
8 6
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
102 bài viết.
252 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!