Mình vào trang dân trí
http://dantri.com.vn/c119/s119-631216/doan-phim-stopmotion-cuc-an-tuong-tao-nen-tu-excel.htm
xem một đoạn clip mà các chuyển động làm từ Excel, cho mình hỏi có phải cái này họ chạy bằng Macro hay VB?
Thực ra làm những cái như thế không khó, với người có chút khái niệm thì là chuyện thường.
1. Phim là gì? Là một chuỗi khung ảnh được chiếu liên tiếp lên màn hình. Bạn vào rạp chiếu phim và nhờ bác chiếu phim cho xem các thước phim thì sẽ thấy chúng là một loạt khung ảnh. Nếu các khung ảnh đều giống nhau thì cũng là phim. Bạn xem một bộ phim có cảnh ông sư ngồi thiền trong 1 phút không cử động. Thì các khung ảnh trong 1 phút đó giống nhau thôi chứ không phải máy chiếu lúc đó bị "kẹt". Nếu các khung ảnh liên tiếp khác nhau rất ít, chỉ một chi tiết nhỏ, và tốc độ chiếu phù hợp thì bạn thấy phim "chạy" mượt, các chuyển động hài hòa. Về chi tiết vd. khung 1 là ảnh cô gái ngả đầu về bên trái khung thứ hai ngả đầu về bên phải thì dĩ nhiên bạn thấy phim hơi kỳ. Làm gì có chuyện thần tiên thế. Phải có những khung ảnh trung gian: cô gái đưa dần đầu về vị trí thẳng, sau đó đưa dần về bên phải. Về tốc độ thì nếu bạn chiếu "bình thường" thì thấy cô gái đang đi, chiếu nhanh thì thấy cô ta như chạy, còn chiếu chậm thì thấy như cô ta đang "lết". Tất nhiên chiếu "bình thường" thì phim cũng bị "giật cục" nhưng người ta đã nghiệm ra rằng nếu chiếu với tốc độ 25 khung ảnh trong 1 giây thì độ "giật cục" nhỏ tới mức mắt thường không phân biệt được, tức phim chạy mượt.
Tóm lại muốn có phim thì phải có một loạt ảnh. Bạn mở phim trên PC rồi đọc thì thấy nó có bao nhiêu frame.
2. Làm thế nào có được các khung ảnh - frame? Có thể lập trình để "moi" chúng ra. Nhưng tất nhiên nếu không là người lập trình chuyên làm sản phẩm phim ảnh thì không ai làm mọi việc từ "số không" cả. Có nhiều phần mềm cho phép bạn xuất tất cả các frames trong phim ghi ra đĩa.
3. Vậy có ảnh rồi thì chiếu liên tiếp thành phim thôi. Ta xét việc chiếu 1 ảnh, các ảnh khác thì chiếu tương tự thôi.
Trong chủ đề này bạn ndu gợi lại chủ đề cũ. Trong vd. ở chủ đề đó tác giả nhập ảnh vào 1 sheet, click chuột để xác định vùng rồi dùng GetPixel để đọc mầu của từng điểm trong ảnh rồi "nhập" vào các cell của sheet thứ hai. Đây cũng là một cách. Nhưng có thể không dùng sheet phụ và thao tác tự động hơn. Có thể để ảnh ở ngoài rồi dùng code đọc vào bộ nhớ rồi nhập nó vào một device context rồi dùng GetPixel để đọc mầu. Cũng không cần click gì để xác định vùng ảnh vì kích thước của ảnh có thể đọc bằng code. Trong code ví dụ tôi làm việc này trong sub Test, kích hoạt bằng nút Test1.
Cũng cần nói thêm là không nhất thiết phải dùng GetPixel. Và thêm nữa vd. nếu ta có ảnh BMP 256 mầu thì mầu của các pixel có thể đọc trực tiếp từ tập tin đã load vào bộ nhớ (không có device context, GetPixel gì cả). Đơn giản vì BMP 256 mầu có cấu trúc rất đơn giản. Ở đầu là cấu trúc header, sau nữa là ..., sau nữa là mảng bai có độ lớn = a * b với a, b là 2 kích thước của ảnh (gọi là mảng A), cuối tập tin là một mảng có độ lớn = 3*256 = 768 bai, ta gọi là mảng B - bảng mầu.
Mỗi một bai của mảng A "đại diện" cho 1 pixel trong ảnh. Nhưng đó không phải là giá trị mầu của điểm đó. Bai đó là chỉ số (index) tới bảng mầu B. Bảng B định nghĩa 256 mầu được dùng trong ảnh hiện hành, mỗi mầu được xác định bởi 3 bai là các thành phần Red, Green, Blue. Vị trí của mảng A, B được xác định bằng các offset tính từ đầu tập tin. Các offset này đọc được từ header là một cấu trúc nhất định được định nghĩa bởi Windows. Vậy ta chỉ cần load tập tin vào bộ nhớ --> đọc cấu trúc header --> xác đinh offset của mảng A, B để về sau nhẩy tới đầu của các mảng --> đọc lần lượt các bai trong mảng A ta có index của mầu trong mảng B --> nhẩy tới điểm đầu P của mảng B --> đọc 3 bai ở vị trí tính từ P là 3*index, 3*index + 1, 3*index + 2 --> có 3 thành phần Red, Green, Blue thì mầu của điểm là RGB(red, Green, Blue)
Với các định dạng khác thì phải dùng nhiều hàm của system hơn. Tất nhiên ta mới xét bitmap. Nếu JPG chẳng hạn thì cũng có thể dùng component của bên thứ ba.
4. Thế nếu có phim 1000 khung ảnh thì chả nhẽ để chúng nằm tơ hơ trong thư mục? Có thể gói chúng lại, thậm chí nén trong 1 tập tin. Rồi trong code đọc từng khung ra để xử lý. Cũng có thể dùng code ở điểm 3 để đọc mầu các điểm và ghi lên đĩa chứ không "nhập" xuống sheet. Sau đó trong quá trình "biểu diễn" thì đọc mầu từ tập tin trên đĩa và "nhập" xuống sheet. Với tập tin vd. của tôi thì đọc tập tin khoảng < 0,001 giây trên máy cũ của tôi.
Trong nút Test2 tôi dùng cách đọc mầu từ tập tin đã soạn sẵn. Nói chung cách 3 và 4 tức độ tương đương nhau.
5. Tốc độ test ở điểm 3, 4 chậm, trên máy cũ của tôi thì có khi là ~ 40 giây. Thì dĩ nhiên rồi. Cái lâu nhất là nhập xuống sheet vì các khâu khác chỉ mất khoảng 0,01 giây.
Excel được thiết kế để làm việc khác chứ không phải để chiếu phim nên nhập vào sheet lâu là đúng rồi.
Bạn xem clip của anh chàng nọ thì thấy ảnh của anh ta có rất ít pixel, do vậy để nhìn được thì mỗi cell của anh ta lớn. Kết quả là chỉ nhìn thấy "bóng ma" đang nhẩy chứ không có chi tiết. Chỉ cần ảnh của anh ta có mỗi chiều bằng 1 / 5 mỗi chiều của ảnh "bình thường" thì số pixel của anh ta giảm được 25 lần và do vậy tốc độ nhập vào sheet cũng giảm đi 25 lần. Thay vì 25, 50 giây thì anh ta chỉ cần 1, 2 giây.
Chuyện thay đổi mầu cho từng cell là lâu, nhưng nếu không thay mầu của từng cell mà lại "vẽ" ảnh lên nền Excel thì lại nhanh vô cùng. Trên máy của tôi việc vẽ này chỉ khoảng <= 0,001 giây
Tôi cho vd. về vẽ trong sub ve() kích hoạt bằng nút "Ve len cua so".
Tôi nó sơ về "triết lý" thôi chứ không có ý định làm phim trên Excel. Vì có cố làm thì chất lượng ảnh không cao và tốc độ không thể chạy mượt được. Tôi cho vd. với ảnh 100x100 pixel. Thế nếu phim 320X240 thì sao? Thì tốc độ còn chậm đi 7,68 lần. Có cải thiện tốc độ bằng cách nào thì vẫn không thể chạy mượt được.
Làm một cái gì đó để chơi trong 1 ngày rồi bỏ (vì Excel không phải là chỗ chiếu phim) thì chắc chắn tôi không thử.