Đoạn phim stop-motion người ta dùng Macro hay VB??? (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Ông này chắc cũng nghiện Excel và VBA đây! Hay hay --=0
 
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?

Cái này phải lập trình cho Excel để ghi điểm ảnh. Lập trình có thể dùng nhiều ngôn ngữ: VB6, .NET, DELPHI, C++,....
Kỹ thuật làm cái này giống hoạt hình, theo nguyên lý 1 giây = 24 hình, sự thay đổi hình ảnh sau phủ nhật hình ảnh trước trở thành sự chuyển động của clip. Việc vất vả là phải có công cụ gi lại các điểm ảnh của đối tượng theo từng khung hình.
 
Cái này phải lập trình cho Excel để ghi điểm ảnh. Lập trình có thể dùng nhiều ngôn ngữ: VB6, .NET, DELPHI, C++,....
Kỹ thuật làm cái này giống hoạt hình, theo nguyên lý 1 giây = 24 hình, sự thay đổi hình ảnh sau phủ nhật hình ảnh trước trở thành sự chuyển động của clip. Việc vất vả là phải có công cụ gi lại các điểm ảnh của đối tượng theo từng khung hình.
Trước đây GPE cũng từng làm tương tự thế!
Hình như là cái này (dùng hàm API)
http://www.giaiphapexcel.com/forum/showthread.php?50088-Đố-vui-mừng-sinh-nhật-GPE-lần-5
Ở đây là hình tỉnh... nếu hình động thì chắc cũng tương tự, sẽ cắt lấy mỗi giây chừng 10 đến 20 hình cũng đủ rồi
 
Trước đây GPE cũng từng làm tương tự thế!
Hình như là cái này (dùng hàm API)
http://www.giaiphapexcel.com/forum/showthread.php?50088-Đố-vui-mừng-sinh-nhật-GPE-lần-5
Ở đây là hình tỉnh... nếu hình động thì chắc cũng tương tự, sẽ cắt lấy mỗi giây chừng 10 đến 20 hình cũng đủ rồi

Việc tô màu trên Excel sheet không cần API, còn nếu lấy điểm ảnh thì phải dùng nó để nhận từng điểm. Việc quan trọng nữa là phải map cặp màu trên Excel và từ hàm API. Ví dụ như màu đỏ trên hàm API là 2, nhưng trong Excel lại là 34 chăng hạn.
 
Việc tô màu trên Excel sheet không cần API, còn nếu lấy điểm ảnh thì phải dùng nó để nhận từng điểm. Việc quan trọng nữa là phải map cặp màu trên Excel và từ hàm API. Ví dụ như màu đỏ trên hàm API là 2, nhưng trong Excel lại là 34 chăng hạn.
Hổng ấy GPE mình cũng làm 1 cái biểu diễn xem
Mình nghĩ tầm cở Tuân chắc thừa sức
(để bà con biết GPE mình cũng "ngầu" như ai)
Ẹc... Ẹc...
 
Hổng ấy GPE mình cũng làm 1 cái biểu diễn xem
Mình nghĩ tầm cở Tuân chắc thừa sức
(để bà con biết GPE mình cũng "ngầu" như ai)
Ẹc... Ẹc...

Tầm như anh cũng thừa cơ đấy chứ...Ẹc ẹc. Anh em động viên nhau làm nhỉ. Vụ này mà làm chắc cũng nguốn mất vài tuần (chủ yếu là quay phim & tách ảnh, lấy màu), khi nào xin vợ nghỉ phép thì làm chơi coi.
 
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?
Để tạo nên đoạn clip đó thì không cần đến 1 đoạn code VBA nào cả bạn ah. Bản thân bài báo cũng lý giải điều đó.
dân trí đã viết:
Với bộ phim stop-motion được anh thực hiện trên nền của phần mềm Excel, trong đó anh sử dụng bảng màu để tạo nên màu sắc cho các bảng tính, tương đương với màu của một điểm ảnh, sau đó lần lượt thay đổi màu sắc của các bảng tính Excel để tạo nên chuyển động cho đoạn phim.
Để có thể lý giải cách thực hiện đoạn clip trên mình sẽ đưa ra một số nguyên lý sau:
Khi bạn xem 1 đoạn clip, tốc độ hiện thị khung ảnh có thể là 14khung/giây hoặc nhiều hơn, nhưng thực sự không hẳn phải vẽ đủ cả 14 khung ảnh. Có thể chỉ cần một hoặc vài khung ảnh nhưng được lập lại liên tiếp trong giây đó.
Với độ nhạy của thị giác con người thì bạn chỉ cần 3-4 khung/giây là có thể "cảm giác" được hình ảnh chuyển động tương đối sinh động.
dân trí đã viết:
Joe Penna đã phải mất đến 5 tiếng đồng hồ cho một đoạn phim ngắn chưa đến 1 phút.
Giả sử mỗi giây, Joe Penna cần tạo ra 3 khung ảnh, vậy thì với 1 đoạn phim dài chưa đến 1 phút (60 giây), anh ta sẽ cần tạo ra khoảng 180 khung hình. Trong 5 tiếng đồ hồ (300 phút) anh ta tạo ra khoảng 180 khung hình, tương ứng mỗi 1,7 phút Joe Penna tạo ra khoảng 1 khung hình.
Tốc độ vẽ có vẻ không tưởng cho lắm. Tuy nhiên trong hoạt hình, thời gian vẽ bức bắt đầu 1 chuyển động, và kết thúc 1 chuyển động là lâu nhất. Còn những bức vẽ "biến đổi" giữa bức "khởi đầu" và "kết thúc" thực hiện nhanh hơn nhiều lần bởi dựa vào bức đầu tiên.
Bằng một chút chỉnh sửa (chẳng hạn nâng tay trái cao hơn, chân trái đá sang phải...) dựa trên bức hình khỏi đầu, người hoạ sĩ sẽ có bức ảnh thứ 2 với khoảng thời gian chỉ bằng 1 phần rất nhỏ so với bức ảnh khởi điểm. Dựa trên bức ảnh thứ 2, người hoạ sĩ sẽ dễ dàng thực hiện tiếp bức thứ 3,4...
Vậy với bức khởi đầu/kết thúc trong một đoạn, Joe Penna tốn khoảng 3 phút, và khoảng hơn 1 phút cho các khung ảnh chuyển tiếp.
Tốc độ vẽ đó vẫn khiến bạn nghi ngờ?
Nếu có dịp quan sát công việc của một hoạ viên hoạ hình thì bạn sẽ không phải nghi ngờ tốc độ trên. Bạn sẽ bất ngờ bởi thao tác rất thành thục và lanh lẹ của của một hoạ viên viên hoạt hình. Với một bậc thầy như Joe Penna thì tốc độ làm việc còn có thể gấp 3-4 lần so với một chuyên viên đồ hoạ bình thường.
...và kết quả thực sự ấn tượng, khiến người xem phải thán phục bởi sự tinh tế và đặc biệt là sự kiên nhẫn của Penna.
Đấy là những nét cơ bản về công việc của Joe Penna khi tạo nên đoá clip sinh động trên. Ngoài sự kỳ công tỷ mỷ cũng còn cần tới tài năng của bậc thầy về hoạt hoạ Joe Penna nữa.
Mình đưa ra ý kiến trên dựa trên kinh nghiệm từng làm hoạ viên hoạt hình thôi. Với các bậc thầy về VBA thì việc thực hiện đoạn clip trên có thể còn có cách nào khác?
 
Để tạo nên đoạn clip đó thì không cần đến 1 đoạn code VBA nào cả bạn ah. Bản thân bài báo cũng lý giải điều đó.

Để có thể lý giải cách thực hiện đoạn clip trên mình sẽ đưa ra một số nguyên lý sau:
Khi bạn xem 1 đoạn clip, tốc độ hiện thị khung ảnh có thể là 14khung/giây hoặc nhiều hơn, nhưng thực sự không hẳn phải vẽ đủ cả 14 khung ảnh. Có thể chỉ cần một hoặc vài khung ảnh nhưng được lập lại liên tiếp trong giây đó.
Với độ nhạy của thị giác con người thì bạn chỉ cần 3-4 khung/giây là có thể "cảm giác" được hình ảnh chuyển động tương đối sinh động.

Giả sử mỗi giây, Joe Penna cần tạo ra 3 khung ảnh, vậy thì với 1 đoạn phim dài chưa đến 1 phút (60 giây), anh ta sẽ cần tạo ra khoảng 180 khung hình. Trong 5 tiếng đồ hồ (300 phút) anh ta tạo ra khoảng 180 khung hình, tương ứng mỗi 1,7 phút Joe Penna tạo ra khoảng 1 khung hình.
Tốc độ vẽ có vẻ không tưởng cho lắm. Tuy nhiên trong hoạt hình, thời gian vẽ bức bắt đầu 1 chuyển động, và kết thúc 1 chuyển động là lâu nhất. Còn những bức vẽ "biến đổi" giữa bức "khởi đầu" và "kết thúc" thực hiện nhanh hơn nhiều lần bởi dựa vào bức đầu tiên.
Bằng một chút chỉnh sửa (chẳng hạn nâng tay trái cao hơn, chân trái đá sang phải...) dựa trên bức hình khỏi đầu, người hoạ sĩ sẽ có bức ảnh thứ 2 với khoảng thời gian chỉ bằng 1 phần rất nhỏ so với bức ảnh khởi điểm. Dựa trên bức ảnh thứ 2, người hoạ sĩ sẽ dễ dàng thực hiện tiếp bức thứ 3,4...
Vậy với bức khởi đầu/kết thúc trong một đoạn, Joe Penna tốn khoảng 3 phút, và khoảng hơn 1 phút cho các khung ảnh chuyển tiếp.

Nếu có dịp quan sát công việc của một hoạ viên hoạ hình thì bạn sẽ không phải nghi ngờ tốc độ trên. Bạn sẽ bất ngờ bởi thao tác rất thành thục và lanh lẹ của của một hoạ viên viên hoạt hình. Với một bậc thầy như Joe Penna thì tốc độ làm việc còn có thể gấp 3-4 lần so với một chuyên viên đồ hoạ bình thường.

Đấy là những nét cơ bản về công việc của Joe Penna khi tạo nên đoá clip sinh động trên. Ngoài sự kỳ công tỷ mỷ cũng còn cần tới tài năng của bậc thầy về hoạt hoạ Joe Penna nữa.
Mình đưa ra ý kiến trên dựa trên kinh nghiệm từng làm hoạ viên hoạt hình thôi. Với các bậc thầy về VBA thì việc thực hiện đoạn clip trên có thể còn có cách nào khác?

Thực ra bài báo chỉ ghi nhận theo quan sát. Lời nói của tác giả cũng chỉ nói cơ bản cách làm. Việc dùng bảng màu là đương nhiên vì nó phải tương thích với ảnh chụp. Nhưng chỉ là bảng mầu thôi thì không thể làm được. Với việc vẽ thì chọn ra bảng mầu mới chỉ là lấy ra hộp bút vẽ chứ vẽ hình như thế nào thì là con người chỉ định.

Nếu tác giả không dùng code để tự động hóa việc tô màu trên từng ô thì tôi cảm phục vì sự kiên nhẫn và tỉ mỉ - Anh ta ngồi so sánh bằng mắt (có thể so sánh với ảnh gốc theo tọa đổ điểm ảnh) và dùng chuột tô từng cell với fill color.

Nếu các bạn để ý trong clip, ở thanh địa chỉ (phía trái thanh Formula) thì thấy các địa chỉ ô thay đổi khi hình chuyển động, điều này có thể là:
1. Anh ta dùng chuột bấn từng ô để tô màu - cực kỳ tỉ mỷ và mất nhiều time.
2. Dùng code để chọn ô và tô mầu. Như clip thì điạ chỉ ô thay đổi liên tục, vậy trước khi tô màu, tác giả dùng lệnh Select rồi tô màu. Thực ra nếu làm làm VBA kinh nghiệm thì không dùng Select mà vẫn tô màu theo địa chỉ ô được, khi đó ta sẽ không thấy địa chỉ ô thay đổi trên clip.

Tôi chắc rằng, nếu với việc viết code thì để làm clip trên thì đỡ mất sức và time hơn rất nhiều. Thời gian mất nhiều là quay phim và cắt những hình cần thiết. Việc lấy các điểm mầu trên ảnh tô vào Cell cũng dùng code hoàn toàn được.
 
Lần chỉnh sửa cuối:
Thực ra bài báo chỉ ghi nhận theo quan sát. Lời nói của tác giả cũng chỉ nói cơ bản cách làm. Việc dùng bảng màu là đương nhiên vì nó phải tương thích với ảnh chụp. Nhưng chỉ là bảng mầu thôi thì không thể làm được. Với việc vẽ thì chọn ra bảng mầu mới chỉ là lấy ra hộp bút vẽ chứ vẽ hình như thế nào thì là con người chỉ định.

Nếu tác giả không dùng code để tự động hóa việc tô màu trên từng ô thì tôi cảm phục vì sự kiên nhẫn và tỉ mỉ - Anh ta ngồi so sánh bằng mắt (có thể so sánh với ảnh gốc theo tọa đổ điểm ảnh) và dùng chuột tô từng cell với fill color.

Nếu các bạn để ý trong clip, ở thanh địa chỉ (phía trái thanh Formula) thì thấy các địa chỉ ô thay đổi khi hình chuyển động, điều này có thể là:
1. Anh ta dùng chuột bấn từng ô để tô màu - cực kỳ tỉ mỷ và mất nhiều time.
2. Dùng code để chọn ô và tô mầu. Như clip thì điạ chỉ ô thay đổi liên tục, vậy trước khi tô màu, tác giả dùng lệnh Select rồi tô màu. Thực ra nếu làm làm VBA kinh nghiệm thì không dùng Select mà vẫn tô màu theo địa chỉ ô được, khi đó ta sẽ không thấy địa chỉ ô thay đổi trên clip.

Tôi chắc rằng, nếu với việc viết code thì để làm clip trên thì đỡ mất sức và time hơn rất nhiều. Thời gian mất nhiều là quay phim và cắt những hình cần thiết. Việc lấy các điểm mầu trên ảnh tô vào Cell cũng dùng code hoàn toàn được.
Mình chỉ diễn giải vấn đề này theo góc nhìn của người từng làm hoạt hoạ thôi, còn VBA chắc là ngoài tầm với của mình rồi. Cho nên không thể lý giải cách thực hiện theo phương pháp của các bậc thầy VBA được. Và nếu chỉ với 5h để một mình có thể tạo ra một chương trình VBA thông minh như vậy chắc đến Bill Gates cũng phải lặn lội đến để bái làm sư phụ.
 
Lần chỉnh sửa cuối:
Và nếu chỉ với 5h để một mình có thể tạo ra một chương trình VBA thông minh như vậy chắc đến Bill Gates cũng phải lặn lội đến để bái làm sư phụ.
Ấy! Hoàn toàn làm được nếu dùng VBA, thậm chỉ là rất dễ nữa là đàng khác
Việc của anh họa sĩ chỉ là "chọn lựa các khung hình phù hợp" ---> Xong, cho vào Excel để nó scan ra điểm ảnh
Về vụ scan này thì GPE đã làm từ lâu rồi (link tôi cho ở trên đấy)
 
Ấy! Hoàn toàn làm được nếu dùng VBA, thậm chỉ là rất dễ nữa là đàng khác
Việc của anh họa sĩ chỉ là "chọn lựa các khung hình phù hợp" ---> Xong, cho vào Excel để nó scan ra điểm ảnh
Về vụ scan này thì GPE đã làm từ lâu rồi (link tôi cho ở trên đấy)
Nếu là chuyện chuyển clip quay sống thành clip chụp trên Excel thì khác nào nào lấy bột xay... làm bột rồi anh. Chắc em cũng bắt trước làm 1 cái để được nhấn like trên youtube.
 
Lần chỉnh sửa cuối:
Nếu là chuyện chuyển clip quay sống thành clip chụp trên Excel thì khác nào nào lấy bột xay... làm bột rồi anh. Chắc em cũng bắt trước làm 1 cái để được nhấn like trên youtube.
Gì cũng được... Vấn đề là ĐÂU PHẢI AI CŨNG BIẾT LÀM THEO CÁCH NÀY
Vôi tôi, cách nào nhanh thì tôi dùng ---> Công cụ mà ta học để làm quái gì, chẳng lẽ DÙNG TAY làm thì mới PRO à?
Vì thế mà tôi rất muốn xem tận mắt cái file Excel ấy (không phải qua đoạn video) để xem thử "tay ấy" ngầu cở nào
 
Nhanh là bao lâu?
Thời gian anh viết 1 chương trình như thế?
Thời gian cần để tạo ra dữ liệu đầu vào?
Thời gian để chỉnh sửa, chọn lọc dữ liệu đầu vào phù hợp?
Và chương trình đó cho ra dữ liệu đầu ra là gì? 1 Clip hoàn chỉnh luôn không?
Nếu không ra một clip hoàn chỉnh, vậy cần bao nhiêu thời gian để tạo ra clip dựa trên dữ liệu đầu ra của chương trình đó và cần sử dụng thêm phần mềm hỗ trợ nào nữa ko?
5h để làm tất cả những công việc ở trên đó.
Nếu chú ý 1 tý thì chúng ta có thể thấy clip đó là 1 sản phẩm hoạt hoạ 2D dạng "low resolution pixel art" tạm hiểu là "nghệ thuật với độ phân giải thấp" đặc trưng bởi những điểm ảnh rời rạc khi phóng to khung hình chuyển động.

Ứng dụng nghệ thuật này rất phổ biến trên nền mobile nhất là với game. Để tạo nên những game dạng này thì người ta cần đến những hoạ sĩ chuyên về lĩnh vực trên và những hoạ sĩ này có lương không hề rẻ và tốn khá nhiều công sức cho chỉ một game nhỏ.

Vậy nếu có thể tạo ra những phần mềm như anh nói thì cần gì phải thuê những hoạ sĩ như vậy? Và nếu ai có thể tạo ra những phần mềm như vậy chắc chắn sẽ có cơ hội thành triệu phú?

Nói về phần mềm hỗ trợ hoạt hoạ hiện nay thì chỉ có phần mềm 3D cụ thể là 3DSMax và Mayar là thành công. Còn các phần mềm hoạt hoạ 2D thì chỉ mới đạt tới mức hỗ trợ người vẽ chứ ko thể hoàn toàn thay thế. Ngay cả với Nhật Bản - nước có công nghệ làm hoạt hình nổi tiếng hiện cũng phải thuê thợ vẽ tận Việt Nam và nhiều nước khác chứ họ cũng không thể tạo nên một phần mềm diễn hoạt sinh động như người vẽ.
 
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ử.
 

File đính kèm

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ý.
Thực tế thì vấn đề này có vẻ không đúng lắm. Xử lý 1 tập tin bình thường (chưa nén) bao giờ cũng nhanh hơn nhiều so với 1 tập được nén, vì xử lý 1 tập tin bị nén sẽ bao gồm cả thời gian giải nén, ghi ra file rồi đọc lại file vào bộ nhớ (nếu không giải nén trực tiếp vào bộ nhớ). Với nhiều định dạng nén, kể cả giải nén 1 tập tin trong 1000 được nén chung thì cũng tốn thời gian gần bằng với giải nén 1000 (chỉ bớt được thời gian ghi ra 999 file). Nếu anh đã từng thử qua sẽ biết.

Mình có thử chương trình của anh siwtom ở các độ phân giải khác nhau và thu được tốc độ hiện thị như sau:

  1. Thử 1: 100x100 (10.000 điểm ảnh): tốc độ hiển thị bình quân khoảng 1 khung hình/20s.
  2. Thử 2: 60x60 (3.600 điểm ảnh): tốc độ hiện thị bình quân gần 1 khung hình/8s.
  3. Thử 3: 30x30 (900 điểm ảnh): tốc độ hiện thị bình quân gần 1 khung hình/3s.

Mình có thử đếm số điểm ảnh mà anh hoạ sĩ sử dụng vào khoảng 45x80 (3.600 điểm ảnh) tương đương phép thử 2.

Để bảo đảm tính khách quan của phép thử mình đã tắt hết các chương trình khác kể cả Internet Explorer đang mở GPE.

Như vậy để Excel có thể trình diễn 1 đoạn clip với tốc độ tối thiểu 3 khung hình trên giây (đủ tạo cảm giác chuyển động) thì cần phải có tốc độ gấp 24 lần tốc độ xử lý hiện tại của cái máy tính cũ mình đang sử dụng...

Như vậy ngoài khả năng về hoạt hoạ thì anh hoạ sĩ này cũng là 1 bậc thầy về VBA đồng thời sở hữu 1 chiếc máy tính dù không xếp hạng siêu thì cũng phải rất khủng.

Còn nếu dùng 1 chiếc máy tính thông thường thì có lẽ Excel sẽ trình diễn 1 đoạn clip ...giật cục nhất trên youtube vì khoảng 1 vài giây mới nhảy được 1 khung hình... Trừ khi anh hoạ sĩ này chụp lại từng khung hình một và chuyển sang một phần mềm dựng phim để đẩy nhanh tốc độ hiển thị. Àh cái này thì mình có thấy ở 1 tích tắc của đoạn clip.

Mặt khác, anh hoạ sĩ buộc phải biên tập trước 1 đoạn video trước đó vì theo tác giả diễn viễn cũng chính là nhà sản xuất.
Như vậy anh ta sẽ phải thực hiện ít nhất những việc sau:

  1. Sửa soạn đạo cụ, trang phục và 1 kịch bản ngắn.
  2. Diễn, dừng và chỉnh lại góc quay... và diễn..
  3. Chọn ra những đoạn ưng ý, biên tập lại đoạn clip được quay.
  4. Chuyển đoạn clip về độ phân giải thấp phù hợp.
  5. Dùng chương trình bóc đoạn clip ấy ra khoảng 14x60=840 khung ảnh.
  6. Cắm cụi viết 1 chương trình VBA giúp anh ta hiện thị lại số ảnh nói trên.
  7. Nếu không có hoặc không thể mượn được 1 chiếc máy tính đủ tốc độ để trình diễn số ảnh trên 1 cách mượt mà, thì anh ta sẽ buộc phải dựng lại 840 khung ảnh đã được bóc ra từ clip thành 1 cái clip khác.

Cuối cùng 1 sản phẩm không khác mấy đoạn clip có độ phân giải thấp ban đầu... Khác chăng nó được hiển thị trên Excel...

Và tôi xin được thán phục trước tiên là kỳ công của anh ta cho 1 sản phẩm như vậy chỉ trong 5 tiếng đồng hồ... Sau đó là ngưỡng mộ sự song toàn gần như hoàn hảo rất nhiều kỹ năng của anh hoạ sĩ đó.
 
Lần chỉnh sửa cuối:
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ử.
Code của bạn rất hay, scan hình ra rất mượt! Đương nhiên vậy là vì bạn format đến 16 triệu màu... và đó cũng là nguyên nhân khiến cho tốc độ chậm
Xem đoạn video clip ở bài 1, hình như người ta chỉ dùng có 56 màu thôi ---> Với lượng màu này thì chắc tốc độ không còn là vấn đề rồi
 
Thực tế thì vấn đề này có vẻ không đúng lắm. Xử lý 1 tập tin bình thường (chưa nén) bao giờ cũng nhanh hơn nhiều so với 1 tập được nén, vì xử lý 1 tập tin bị nén sẽ bao gồm cả thời gian giải nén, ghi ra file rồi đọc lại file vào bộ nhớ (nếu không giải nén trực tiếp vào bộ nhớ). Với nhiều định dạng nén, kể cả giải nén 1 tập tin trong 1000 được nén chung thì cũng tốn thời gian gần bằng với giải nén 1000 (chỉ bớt được thời gian ghi ra 999 file). Nếu anh đã từng thử qua sẽ biết.

Tôi nói về 2 khả năng: nối thành một, và nối thành một đồng thời nén.
Không phải thử gì cả cũng biết bạn nói đúng rồi. Việc giải nén tất nhiên bao giờ cũng lâu hơn đọc 1 tập tin không nén.
Nhưng bạn có nghĩ rằng ta có thể "đẩy" thời gian này sang "mục" soạn thảo chứ không để ở mục "biểu diễn"? Anh chàng nọ mất 5 giờ cho "mục" soạn thảo cơ mà.
Tóm lại: khi mở tập tin thì Macro đọc và giải nén, tách thành 1000 BMP nhỏ - tôi đang xét 1000 ảnh với kích thước 100x100 pixel, ghi lên đĩa. Khi tới phần biểu diễn, tức "người xem" phim nhất nút Test1, thì các tập tin đã chờ sẵn rồi. Khi đóng tập tin thì nó xóa các BMP đã ghi trên đĩa.
 
Code của bạn rất hay, scan hình ra rất mượt! Đương nhiên vậy là vì bạn format đến 16 triệu màu... và đó cũng là nguyên nhân khiến cho tốc độ chậm
Xem đoạn video clip ở bài 1, hình như người ta chỉ dùng có 56 màu thôi ---> Với lượng màu này thì chắc tốc độ không còn là vấn đề rồi

Đúng như bạn nói với bitmap 24 bit thì "giá trị của mầu" có thể lên tới 16777215. Anh chàng nọ dù chỉ dùng 56 mầu nhưng giá trị của mỗi mầu cũng có thể là 16777215 cơ mà. Vd. anh ta dùng các mầu RGB(i, 255, 255) với i = 199-255 thì mỗi mầu có giá trị nằm trong khoảng 16777159-16777215
Nhưng bạn nghi là anh nọ dùng 56 mầu, mà có khi lại đúng 56 mầu của Excel?
Tuy nhiên, rõ ràng là bitmap 100x100 pixel thì có 10.000 điểm ảnh nên chỉ dùng nhiều nhất là 10.000 mầu khác nhau chứ không phải là 16 triệu mầu. Tôi hiểu ý bạn nói là bitmap của tôi dùng "số lượng mầu" nhiều hơn. Để xem ảnh của tôi dùng bao nhiêu mầu khác nhau tôi đọc các giá trị mầu do GetPixel đọc vào mảng các giá trị duy nhất. Kết quả là nó dùng 7.874 mầu khác nhau. Tất nhiên con số này khác 56 rất nhiều. Nhưng ...

1. Tôi thử đọc ảnh 24 bit của tôi vào Paint --> ghi lại ở dạng 256 mầu (tất nhiên sẽ bị mất mầu). Cũng ảnh kích thước như thế nhưng là 256 mầu thì bây giờ vòng lặp
Mã:
    For r = 1 To bmp.bmHeight
        For c = 1 To bmp.bmWidth
            ActiveSheet.Cells(r, c).Interior.color = GetPixel(DC, c - 1, r - 1)
        Next c
    Next r
chạy nhanh hơn gấp 6 lần.

2. Bây giờ tôi lại lưu ảnh nguồn ở dạng 16 mầu thì vòng lặp trên chạy lâu tương tự như vòng lặp cho ảnh ban đầu 24 bit

Phải chăng nếu dùng đúng 56 mầu của Excel thì việc thay đổi thuộc tính "Interior.color" là nhanh nhất???
 
Có lẽ thật dại dột khi cố thực hiện lại công việc của một bậc thầy nào đó +-+-+-+.
Tuy nhiên mình cũng đã cố thử để tìm 1 câu trả lời cho bản thân mình...là liệu Excel có thể chiếu được 1 đoạn phim một cách "mượt mà" ở mức chấp nhận được hay không? hix
 

File đính kèm

Lần chỉnh sửa cuối:
Có lẽ thật dại dột khi cố thực hiện lại công việc của một bậc thầy nào đó +-+-+-+.
Tuy nhiên mình cũng đã cố thử để tìm 1 câu trả lời cho bản thân mình...là liệu Excel có thể chiếu được 1 đoạn phim một cách "mượt mà" ở mức chấp nhận được hay không? hix

Thực ra ta đang bàn về phim của anh chàng nọ.
Và tôi cho là rất khó để làm cái gọi là phim. Vì nếu là phim thực sự thì ngoài chuyện chạy mượt ta còn phải có những cảnh với các chi tiết. "Bóng ma" chuyển động cũng còn chấp nhận được chứ nếu chỉ là hoạt họa những hình thù ngẫu nhiên, các hình vuông, hình tròn thì lại quá dễ.
Để là phim thì phải có chi tiết vậy không thể là 40x40 được, còn nếu lớn quá thì Excel không chiếu mượt được. Có thể vẽ hoạt hình vd. trên nền trắng bằng các đường viền của người và vật bằng mầu đen, mắt mũi ví dụ là những chấm đen, các đường cong đơn giản. Khi ta scan thì chỉ những cell tương ững với các điểm đen trên hình ta mới thay đổi mầu. Như thế thì vd. với hình 40x40 ta không phải thay đổi mầu cho 1600 cell mà chỉ một số ít, nhờ vậy tốc độ animation tăng rõ rệt.
Nếu là animation ngẫu nhiên cái gì đó thì tôi cũng góp vui chút. Nói cho cùng thay cho hình tròn, hình sao ta có thể vẽ những hình đơn giản, chỉ vẽ đường viền của người và vật mà thôi.
 

File đính kèm

1. Tôi thử đọc ảnh 24 bit của tôi vào Paint --> ghi lại ở dạng 256 mầu (tất nhiên sẽ bị mất mầu). Cũng ảnh kích thước như thế nhưng là 256 mầu thì bây giờ vòng lặp
Mã:
    For r = 1 To bmp.bmHeight
        For c = 1 To bmp.bmWidth
            ActiveSheet.Cells(r, c).Interior.color = GetPixel(DC, c - 1, r - 1)
        Next c
    Next r
chạy nhanh hơn gấp 6 lần.

2. Bây giờ tôi lại lưu ảnh nguồn ở dạng 16 mầu thì vòng lặp trên chạy lâu tương tự như vòng lặp cho ảnh ban đầu 24 bit

Phải chăng nếu dùng đúng 56 mầu của Excel thì việc thay đổi thuộc tính "Interior.color" là nhanh nhất???

Nếu là vầy thì sẽ nhanh hơn rất nhiều
PHP:
For r = 1 To height Step lResol
  For c = 1 To width Step lResol
    r1 = Int(r / lResol) + 1
    c1 = Int(c / lResol) + 1
    Arr(r1, c1) = GetPixel(DC, c - 1, r - 1)
  Next c
Next r
Với biến lResol ta cho = 5 chẳng hạn thì việc scan cái hình em be.bmp của bạn gần như diễn ra trong tích tắc
--------------------------
Mình thì không có hứng thú với việc làm video nhưng lại rất hứng thú với code của bạn (scan pic) và muốn nghiên cứu nó để ứng dụng cho những việc khác sau này. Vậy nhân đây mình xin bạn tư vấn giúp 3 câu hỏi dưới đây:
1> Nếu ta dùng file jpg (chứ không phải bmp) thì phải sửa code thế nào?
2> Nếu ta scan hình là 1 object nằm trên bảng tính thì sẽ sửa code thế nào?
3> Chuyển từ Interior.Color sang
Interior.ColorIndex bằng cách nào?
 
Lần chỉnh sửa cuối:
Thực ra ta đang bàn về phim của anh chàng nọ.
Và tôi cho là rất khó để làm cái gọi là phim. Vì nếu là phim thực sự thì ngoài chuyện chạy mượt ta còn phải có những cảnh với các chi tiết. "Bóng ma" chuyển động cũng còn chấp nhận được chứ nếu chỉ là hoạt họa những hình thù ngẫu nhiên, các hình vuông, hình tròn thì lại quá dễ.
Để là phim thì phải có chi tiết vậy không thể là 40x40 được, còn nếu lớn quá thì Excel không chiếu mượt được. Có thể vẽ hoạt hình vd. trên nền trắng bằng các đường viền của người và vật bằng mầu đen, mắt mũi ví dụ là những chấm đen, các đường cong đơn giản. Khi ta scan thì chỉ những cell tương ững với các điểm đen trên hình ta mới thay đổi mầu. Như thế thì vd. với hình 40x40 ta không phải thay đổi mầu cho 1600 cell mà chỉ một số ít, nhờ vậy tốc độ animation tăng rõ rệt.
Nếu là animation ngẫu nhiên cái gì đó thì tôi cũng góp vui chút. Nói cho cùng thay cho hình tròn, hình sao ta có thể vẽ những hình đơn giản, chỉ vẽ đường viền của người và vật mà thôi.

Nếu đi theo quan điểm chỉ dùng chính Excel để trình diễn thì mình có mấy ý sau:

Với hình tròn cỡ 40x40 (khoảng 90 điểm ảnh hữu dụng), còn hình ngôi sao thì ước chừng 110-130 điểm ảnh hữu dụng.

Trên khung hình biểu thị cỡ 45x80=3600. Tỷ lệ điểm ảnh hữu dụng so với diện tích khung hiển thị là 90/3600=2,5%. Với tỷ lệ tương đối lý tưởng này nhưng tốc độ hiện thị vẫn chưa đủ đánh lừa được thị giác. Người xem vẫn cảm giác được rõ là hình đang được vẽ từ trên xuống.

Vậy giả sử hiển thị 1 khung hình có tỷ lệ điểm ảnh hữu dụng là 50% (gấp 20 lần) hoặc bình quân khoảng 10% (gấp 4 lần) thì tốc độ hiển thị sẽ ra sao? Nếu làm như cách anh nói thì chắc chắn tốc độ hiển thị sẽ không đều lúc nhanh (với hình nhỏ) và chậm (nếu hình lớn). Mình có thử chỉnh timer tăng/giảm đi như tốc độ hiển thị cũng không khả quan hơn.

Một vấn đề nữa có liên quan đến ý trước đây là tốc độ hiện thị khung ảnh trong một giây tối thiểu là bao nhiêu để đủ đánh lừa thị giác người xem. Sau khi bắt tay vào làm thử thì mình phát hiện ra rằng:


  1. Với 1 chuyển động tốc độ trung bình thì cũng cần ít nhất khoảng 9 khung ảnh.
  2. Còn với 3 khung ảnh chỉ phù hợp nếu diễn tả 1 chuyển động nhanh hoặc rất nhanh kiểu như 1 chiếc siêu thanh chỉ kịp lưu lại trên võng mạc 1 tấm ảnh của nó trong tích tắc.

Như vậy thì yêu cầu về tốc độ máy tính sẽ ko phải là 24 lần mà phải là 72 lần nhanh hơn. Cứ tạm cho định luật Moore đúng mãi mãi thì cứ sau 1,5 năm tốc độ máy tính nhanh gấp đôi thì chắc cũng cỡ 10 năm nữa 1 cái máy tính bình thường mới có thể làm nhãn quan chúng ta thoả mãn... trừ trường hợp chúng ta có tiền mua 1 chiếc siêu máy tính.

Tuy nhiên nếu có ai đó đang quan tâm vấn đề này thì cũng đừng bi quan như mình... Hiện tại chúng ta vẫn có thể dùng các ô Excel để thực hiện việc chiếu 1 đoạn clip đấy nhé kể cả với 1 độ phân giải không tưởng. Nhưng cách làm sẽ rất khác và sẽ cần nhiều lần của 5 tiếng đồng hồ.
 
Nếu là vầy thì sẽ nhanh hơn rất nhiều
PHP:
For r = 1 To height Step lResol
  For c = 1 To width Step lResol
    r1 = Int(r / lResol) + 1
    c1 = Int(c / lResol) + 1
    Arr(r1, c1) = GetPixel(DC, c - 1, r - 1)
  Next c
Next r
Với biến lResol ta cho = 5 chẳng hạn thì việc scan cái hình em be.bmp của bạn gần như diễn ra trong tích tắc
--------------------------
Mình thì không có hứng thú với việc làm video nhưng lại rất hứng thú với code của bạn (scan pic) và muốn nghiên cứu nó để ứng dụng cho những việc khác sau này. Vậy nhân đây mình xin bạn tư vấn giúp 3 câu hỏi dưới đây:
1> Nếu ta dùng file jpg (chứ không phải bmp) thì phải sửa code thế nào?
2> Nếu ta scan hình là 1 object nằm trên bảng tính thì sẽ sửa code thế nào?
3> Chuyển từ Interior.Color sang
Interior.ColorIndex bằng cách nào?

Bạn xem tạm, tôi sẽ viết cụ thể sau
 

File đính kèm

Bạn xem tạm, tôi sẽ viết cụ thể sau
Lúc nào cũng có những kiến thức mới lạ. Cảm ơn bạn nhé
Hỏi thêm: Có phải hàm GetPictureObject dùng được với Picture nằm trên đĩa hoặc Picture là 1 Object trên bảng tính không?
(hỏi thế là vì mấy cái ghi chú bạn ghi bằng font gì tôi đọc không ra ---> Chỉ đoán)
 
Lúc nào cũng có những kiến thức mới lạ. Cảm ơn bạn nhé
Hỏi thêm: Có phải hàm GetPictureObject dùng được với Picture nằm trên đĩa hoặc Picture là 1 Object trên bảng tính không?
(hỏi thế là vì mấy cái ghi chú bạn ghi bằng font gì tôi đọc không ra ---> Chỉ đoán)

Tôi dùng trong VBE Times: Tools --> OPtions --> thẻ Editor Format --> chọn Times New Roman (vietnamese)
--------------
' loadOpt = 0 --> image là đường dẫn tới tập tin trên đĩa,
' loadOpt = 1 --> image là index của ảnh trong ImageList và obj là ImageList
' loadOpt <> 0 và <> 1--> image là tên của ảnh trên Sheet và obj là tên Sheet đó
--------------
Riêng th nạp từ ImageList và từ Sheet tôi mới viết code, chưa test
-----------------
Handle trong Windows là gì? Nó chẳng qua là một số nguyên. Thế thôi.
Trong công việc hàng ngày bạn có Mã Sản Phẩm, Mã Nhân Viên, ... Để làm gì? Đơn giản để phân biệt. Khi bạn truyền vào hàm Mã Sản Phẩm, Mã Nhân Viên thì hàm biết bạn cần thao tác trên sản phẩm, nhân viên cụ thể nào, bạn muốn truy cập tới sản phẩm, nhân viên nào v...v
Ông Windows thấy "mẹo" của bạn hay quá nên ổng quyết định: tất cả mọi cửa sổ (window), tài nguyên nào được "ta" tạo ra thì "ta" gán cho chúng 1 con số gọi là Handle để phân biệt. Khi người dùng cần thao tác gì (ghi, vẽ, thay đổi các thuộc tính ...) trên một đối tượng nào đó thì gọi hàm thích hợp (hàm ghi tài liệu, vẽ, đọc thuộc tính ...) và truyền Handle của nó vào dưới dạng thông số để "ta" biết được là "ta" cần phải thao tác (ghi tài liệu, vẽ, đọc thuộc tính ...) trên đối tượng nào.
Những combobox, Button, Checkbox ... của Windows đều là window (cửa sổ). Trong notepad chẳng hạn cửa sổ notepad với thanh tiêu đề là 1 window. Nó chứa trong lòng nó window con (lớp - class Edit) - vùng làm việc mầu trắng. Khi bạn chọn Save thì trong cửa sổ Save dòng nhập tên tập tin, nút Save, Cancel, ... đều là window. Tất cả mọi window khi Windows tạo ra đều được "gán" cho 1 con số gọi là Handle (window handle).
Bạn có thể mở 1 tập tin vd. TXT hoặc tạo mới bằng cách gọi hàm CreateFile (phải truyền đường dẫn của tập tin cần mở hoặc cần tạo). Nếu CreateFile mở hoặc tạo thành công thì nó trả về Handle - "handle to the specified file":
Mã:
hFile1 = CreateFile(filename1, ...)
hFile2 = CreateFile(filename2, ...)
Những Handle trả về này Windows dùng để phân biệt. Nếu bạn cần đóng những file được mở được tạo thì bạn gọi hàm CloseHandle. Nhưng để biết bạn cần đóng file nào thì bạn phải truyền Handle vào thì Windows mới biết được ý bạn. Không có Handle thì system không biết bạn định ghi hay đóng file nào:
Mã:
CloseHandle hFile1
Tới đây bạn chỉ có thể thao tác với filename2. Các bước:
Mã:
hFile = CreateFile(filename, ...)
.... các thao tác đọc, ghi gì đó
CloseHandle hFile
Tương tự khi bạn tạo, nạp bitmap, icon, cursor, font, ... thì chúng cũng được gán cho 1 con số gọi là Handle. Trong vd. ở bài trước tôi dùng LoadImage để nạp ảnh vào bộ nhớ. Hàm LoadImage trả vể Handle gọi là "handle of the newly loaded image" mà tôi nhớ vào biến hbmp:
Mã:
hbmp = LoadImage(...)
Tôi nhớ để các bước sau có thể sử dụng bitmap, và về sau giải phóng tài nguyên bitmap:
Mã:
DeleteObject hbmp
Để có thể thao tác thì trước tiên ta phải có Picture. Trong bài trước tôi nạp ảnh BMP bằng LoadImage (chỉ cho icon, cursor, bitmap). Trong bài này để nạp ảnh JPG (tất nhiên không chỉ cho JPG) từ đĩa thì tôi dùng LoadPicture. Nó trả về StdPicture - IPictureDisp, mà StdPicture.Handle - IPictureDisp.Handle chính là "image handle" đã nói ở trên. Tức nếu bài trước tôi có:
Mã:
hbmp = LoadImage(...)
oldBitmap = SelectObject(DC, hbmp)
GetObject hbmp, Len(bmp), bmp
chiều dài ảnh = bmp.bmWidth
chiều cao ảnh = bmp.bmHeight
thì ở bài này tôi làm:
Mã:
Set Pic = LoadPicture(...)
oldPic = SelectObject(srcDC, Pic.Handle)
GetObject Pic.Handle, Len(bmp), bmp
chiều dài ảnh = bmp.bmWidth
chiều cao ảnh = bmp.bmHeight
Tóm lại nếu ta có "bitmap handle" thì coi như "xong". Ở bài trước ta có được Handle bằng cách LoadImage, ở bài này ta gọi LoadPicture để có StdPicture - IPictureDisp, mà StdPicture.Handle - IPictureDisp.Handle chính là cái cần có.
Thế nếu ta có sẵn ảnh ở trên Sheet hoặc trong ImageList rồi thì sao? Thì đọc ra StdPicture - IPictureDisp
Tôi soạn 1 hàm đọc và trả về StdPicture - IPictureDisp khi ta có đường dẫn, ảnh trên Sheet, hoặc trong ImageList.
-------------------
Còn về "Chuyển từ Interior.Color sang Interior.ColorIndex bằng cách nào" thì lẽ ra tôi phải hỏi bạn. Vì bạn có thâm niên trong Excel gấp 9, 10 lần tôi. Nhưng tôi thử "nhìn kỹ" xem vấn đề này như thế nào.
Nếu tôi không lầm thì Excel có 1 bảng mầu "mặc định". Bảng mầu mặc định này chỉ có 56 mầu.
Tôi có thể viết:
Interior.Color = RGB(r, g, b) với r, g, b thuộc [0; 255]. Như thế tôi có thể nhập vào 1 trong 16777216 mầu. Dĩ nhiên trong 16777216 mầu đó có hằng hà sa số mầu không có trong bảng mầu mặc định của Excel nên không có ColorIndex tương ứng. Chỉ khi mầu có mặt trong bảng mầu mặc định thì mới có ColorIndex tương ứng. Vd. mầu có giá trị RGB(0, 0, 0) hoặc RGB(255, 255, 255) có mặt trong bảng mầu mặc định nên tôi có thể:
Mã:
Interior.Color = RGB(0, 0, 0)
hoặc
Interior.ColorIndex = 1
Interior.Color = RGB(255,255, 255)
hoặc
Interior.ColorIndex = 2
Nếu tò mò muốn biết mầu có chỉ số từ 1 tới 56, hay nói cách khác các mầu trong bảng mầu mặc định có các thành phần r, g, b (red, green, blue) như thế nào thì dễ thôi. Bạn biết rồi nhưng tôi mạn phép viết để nhiều bạn nào đọc bài này mà chưa biết thì tham khảo
Mã:
Sub Button1_Click()
Dim k As Long, r As Long, g As Long, b As Long, mau As Long, tmp As Long, Arr(1 To 56) As String
    For k = 1 To 56
        Cells(k, 1).Interior.ColorIndex = k
        mau = Cells(k, 1).Interior.Color
        b = mau \ 65536
        tmp = mau Mod 65536
        g = tmp \ 256
        r = tmp Mod 256
        Arr(k) = "ColorIndex = " & k & ", Color = " & mau & " = RGB(" & r & ", " & g & ", " & b & ")"
    Next k
    Range("B1:B56").Value = Application.WorksheetFunction.Transpose(Arr)
End Sub

Riêng khoản Interior này tôi chỉ viết như tôi tạm hiểu. Chưa chắc tôi đã hiểu đúng hoặc hiểu hết.
 
Cảm ơn bạn về cái Handle, trước đây đã biết, bây giờ lại biết thêm 1 chút
Giải thích rất chi tiết nhưng nói thật lòng là tôi hiểu chắc cở.. 10%
Nhưng không sao... thề với lòng, cái gì tôi muốn biết thì sẽ cố gắng tìm hiểu ---> Thông qua các thí nghiệm để ngộ ra vấn đề (đơn giản vì tôi chưa học qua bất cứ trường lớp nào về Excel hay lập trình)
Một lần nữa cảm ơn bạn! Nếu có vấn đề gì tôi sẽ lại làm phiền tiếp
(Riêng về thằng em Interior.ColorIndex chắc ta sẽ bàn vào 1 topic khác thích hợp. Nói chung là tôi muốn chuyển từ 16 triệu màu sang 56 màu chứ không phải ngược lại)
 
Cảm ơn bạn về cái Handle, trước đây đã biết, bây giờ lại biết thêm 1 chút
Giải thích rất chi tiết nhưng nói thật lòng là tôi hiểu chắc cở.. 10%
Nhưng không sao... thề với lòng, cái gì tôi muốn biết thì sẽ cố gắng tìm hiểu ---> Thông qua các thí nghiệm để ngộ ra vấn đề (đơn giản vì tôi chưa học qua bất cứ trường lớp nào về Excel hay lập trình)
Một lần nữa cảm ơn bạn! Nếu có vấn đề gì tôi sẽ lại làm phiền tiếp
(Riêng về thằng em Interior.ColorIndex chắc ta sẽ bàn vào 1 topic khác thích hợp. Nói chung là tôi muốn chuyển từ 16 triệu màu sang 56 màu chứ không phải ngược lại)

Có một chút gõ thiếu trong hàm GetPictureObject
Dòng
Mã:
If [COLOR=#ff0000]obj[/COLOR].progID = "Forms.Image.1" Then
đổi thành
Mã:
If [COLOR=#ff0000]objOLE[/COLOR].progID = "Forms.Image.1" Then
Tức đổi chỗ mầu đỏ. Cái này ai tinh thì sẽ phát hiện ra dựa trên ngữ cảnh

Tập tin đã sửa, đã test cả 3 kiểu nhập tôi đính kèm ở dưới
 

File đính kèm

Cảm ơn bạn về cái Handle, trước đây đã biết, bây giờ lại biết thêm 1 chút
Giải thích rất chi tiết nhưng nói thật lòng là tôi hiểu chắc cở.. 10%
Nhưng không sao... thề với lòng, cái gì tôi muốn biết thì sẽ cố gắng tìm hiểu ---> Thông qua các thí nghiệm để ngộ ra vấn đề (đơn giản vì tôi chưa học qua bất cứ trường lớp nào về Excel hay lập trình)
Một lần nữa cảm ơn bạn! Nếu có vấn đề gì tôi sẽ lại làm phiền tiếp
(Riêng về thằng em Interior.ColorIndex chắc ta sẽ bàn vào 1 topic khác thích hợp. Nói chung là tôi muốn chuyển từ 16 triệu màu sang 56 màu chứ không phải ngược lại)

Cái chuyện mầu này thì tôi nghĩ "triết lý" đơn giản thôi. Nếu bạn có 1 ảnh nhiều mầu vd. k mầu và bạn muốn convert để nó dùng ít mầu hơn vd. n mầu với k > n thì bao giờ bạn cũng bị mất mầu. Bạn cứ thử nạp vào phần mềm đồ họa bất kỳ rồi ghi lại với ít mầu hơn thì sẽ thấy chất lượng ảnh giảm đi đáng kể. Nhưng các phần mềm đó cũng còn có "lựa chọn" là nó sẽ thay một số mầu bằng những mầu "gần đúng". Còn bạn không có lựa chọn vì rất có thể những mầu có thể gọi là gần đúng đó cũng không có trong bảng 56 mầu của Excel.
Bạn đọc 1 Pixel trong bitmap vd. có mầu là 1800040. Bạn có 56 lựa chọn ColorIndex. Dù chọn ColorIndex nào thì cũng không có mầu nào giống mầu 1800040.
Mã:
Sub Button2_Click()
Dim k As Long
    For k = 1 To 56
        Cells(k, 1).Interior.ColorIndex = k
        Cells(k, 2).Interior.Color = 1800040
    Next k
End Sub
So sánh 2 cột A, B sẽ thấy.
Dù chọn thế nào chăng nữa thì không có chỉ số nào là tốt cả. Bao giờ chất lượng ảnh cũng giảm, có khi rất đáng kể vì bạn chỉ có 56 mầu.
Cái này nó giống như bạn có 56 bút mầu và bạn phải vẽ lại bức tranh mà tác giả dùng 1000 mầu khác nhau. Có thể có những mầu mà 56 bút mầu của bạn không diễn tả được, thậm chí chỉ là gần đúng.
 
Lần chỉnh sửa cuối:
Bạn đọc 1 Pixel trong bitmap vd. có mầu là 1800040. Bạn có 56 lựa chọn ColorIndex. Dù chọn ColorIndex nào thì cũng không có mầu nào giống mầu 1800040.
Mã:
Sub Button2_Click()
Dim k As Long
    For k = 1 To 56
        Cells(k, 1).Interior.ColorIndex = k
        Cells(k, 2).Interior.Color = 1800040
    Next k
End Sub
So sánh 2 cột A, B sẽ thấy.
Dù chọn thế nào chăng nữa thì không có chỉ số nào là tốt cả. Bao giờ chất lượng ảnh cũng giảm, có khi rất đáng kể vì bạn chỉ có 56 mầu.
Cái này nó giống như bạn có 56 bút mầu và bạn phải vẽ lại bức tranh mà tác giả dùng 1000 mầu khác nhau. Có thể có những mầu mà 56 bút mầu của bạn không diễn tả được, thậm chí chỉ là gần đúng.
Nhưng nếu tôi làm vầy thì lại khác:
PHP:
Sub Button2_Click()
  Cells(1, 1).Interior.Color = 1800040
  Cells(1, 2).Interior.ColorIndex = Cells(1, 1).Interior.ColorIndex
End Sub
Cái này là tự Excel nó chuyển lấy và ý tôi muốn tìm cái nguyên tắc này (dù giống hay hơi hơi giống cũng không sao)
 
Cái này là tự Excel nó chuyển lấy và ý tôi muốn tìm cái nguyên tắc này (dù giống hay hơi hơi giống cũng không sao)

1. Dùng hàm của siwtom có thể lấy ra 3 tham số RGB của 56 màu Excel
2. Thử bằng 1 phần mềm đồ họa nào đó (Paint chằng hạn) như sau:

- mở cửa sổ chọn màu có 3 ô RGB
- gõ tham số RGB của 1 màu Excel vào
- thay đổi lần lượt từng tham số R, G, B từng đơn vị một, đến khi nào màu không chấp nhận được nữa.
- Ghi lại phạm vi thay đổi các tham số có thể chấp nhận
- Dùng cách tính ngược với hàm ở bước 1, tính ra phạm vi màu có thể quy về 1 màu thử của Excel.
- chuyển qua màu thử thứ 2 của Excel.
 

Bài viết mới nhất

Back
Top Bottom