Ảnh chụp màn hình Python nhanh
Chúng ta thường chụp ảnh màn hình khi sử dụng máy tính. Cả Windows và Mac đều có chức năng thực hiện việc này một cách dễ dàng Show Nhưng giả sử bạn muốn tự động hóa quy trình này và có thể tự động chụp ảnh màn hình sau mỗi 5 phút hoặc mỗi giờ. Làm thủ công sẽ mất rất nhiều thời gian của bạn và sẽ yêu cầu bạn phải có mặt tại máy tính của mình vào mỗi khoảng thời gian Sử dụng Python, chúng ta có thể dễ dàng tự động hóa tác vụ này và có một số thư viện hỗ trợ chức năng này Để tiếp tục làm theo hướng dẫn này, vui lòng mở “Command Prompt” (trên Windows) và cài đặt các thư viện sau pip install pyautogui Chụp ảnh màn hình với pyautogui trong Python Tùy chọn này có lẽ là nhanh nhất và thuận tiện nhất nếu bạn đang làm việc với một màn hình duy nhất và muốn chụp ảnh toàn màn hình. Ngoài ra, đây cũng là một lựa chọn tốt nếu bạn biết tọa độ của “chiếc hộp” mà bạn muốn chụp màn hình Bắt đầu với việc nhập thư viện pyautogui Sau đó gọi. phương thức chụp màn hình (), sẽ trả về và đối tượng Hình ảnh. Và chỉ cần lưu nó bằng bất kỳ tên tệp nào phù hợp với bạn Và bạn sẽ nhận được một. png trong cùng thư mục với mã Python của bạn Dưới đây là một ví dụ về ảnh chụp màn hình của tôi trông như thế nào Hình ảnh của tác giảMột vài giây sau khi bạn chạy mã,. tệp png sẽ xuất hiện trong thư mục Hình ảnh của tác giảChụp ảnh màn hình bằng PIL trong Python PIL là một trong những thư viện Python nổi tiếng nhất để làm việc với hình ảnh và được sử dụng rộng rãi để xử lý hình ảnh Không có gì ngạc nhiên khi mong đợi chức năng chụp màn hình được bao gồm trong đó. Tương tự như giải pháp pyautogui, PIL cũng cho phép chụp ảnh màn hình bằng Python trong ba dòng mã Bắt đầu với việc nhập mô-đun ImageGrab từ thư viện PIL Sau đó gọi. phương thức grab(), sẽ trả về và đối tượng Image. Và chỉ cần lưu nó bằng bất kỳ tên tệp nào phù hợp với bạn Hình ảnh của tác giảMột vài giây sau khi bạn chạy mã,. tệp png sẽ xuất hiện trong thư mục Hình ảnh của tác giảChụp ảnh màn hình nhiều màn hình bằng mss trong Python Trong các phần trước, chúng tôi đã xem xét việc chụp ảnh màn hình của từng màn hình. Bây giờ, nếu bạn có hai màn hình và bạn muốn chụp ảnh màn hình của cả hai thì sao? Python có một thư viện tuyệt vời mss, cho phép bạn dễ dàng làm điều đó trong một vài bước Bắt đầu với việc nhập thư viện Bây giờ, để chụp ảnh màn hình đang làm việc hiện tại, bạn chỉ cần sử dụng Trong trường hợp có nhiều màn hình và tất cả những gì bạn cần làm là đặt đoạn mã trên vào một vòng lặp và thêm tham số mon Hình ảnh của tác giảvà Hình ảnh của tác giảMột vài giây sau khi bạn chạy mã, hai. các tệp png sẽ xuất hiện trong thư mục Hình ảnh của tác giảPhần kết luận Trong bài viết này, chúng ta đã thảo luận về cách tự động chụp ảnh màn hình bằng một số thư viện trong Python Vui lòng để lại nhận xét bên dưới nếu bạn có bất kỳ câu hỏi nào hoặc có đề xuất cho một số chỉnh sửa và xem thêm các bài viết về Lập trình Python của tôi D3DShot là một triển khai Python thuần túy của Windows Desktop Duplication API. Nó tận dụng các thư viện hệ thống DXGI và Direct3D để kích hoạt chức năng chụp ảnh màn hình cực nhanh và mạnh mẽ cho các tập lệnh và ứng dụng Python của bạn trên Windows D3DShot
Mẫu mã nhanh TL; DRẢnh chụp màn hình vào bộ nhớ import d3dshot d = d3dshot.create() d.screenshot()
Ảnh chụp màn hình vào đĩa import d3dshot d = d3dshot.create() d.screenshot_to_disk()
Chụp màn hình trong 5 giây và lấy khung hình mới nhất import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()
Chụp màn hình Màn hình thứ hai dưới dạng mảng NumPy trong 3 giây và lấy 4 khung hình mới nhất làm ngăn xếp import d3dshot import time d = d3dshot.create(capture_output="numpy") d.display = d.displays[1] d.capture() time.sleep(3) # Capture is non-blocking so we wait explicitely d.stop() frame_stack = d.get_frame_stack((0, 1, 2, 3), stack_dimension="last") frame_stack.shape
Điều này hầu như không làm trầy xước bề mặt. Hãy đọc tiếp Yêu cầu
Cài đặt
D3DShot tận dụng các tệp DLL đã có sẵn trên hệ thống của bạn nên các phần phụ thuộc rất nhẹ. cụ thể là
Các phần phụ thuộc này sẽ tự động được cài đặt cùng với D3DShot; Bước bổ sung. Người dùng máy tính xách tayWindows có một nhược điểm khi sử dụng Sao chép màn hình trên các hệ thống GPU lai. Vui lòng xem bài viết wiki trước khi thử sử dụng D3DShot trên hệ thống của bạn Các khái niệmChụp đầu raĐầu ra chụp mong muốn được xác định khi tạo phiên bản D3DShot. Nó xác định loại của tất cả các hình ảnh được chụp. Theo mặc định, tất cả ảnh chụp sẽ trả về PIL. Đối tượng hình ảnh. Đây là một lựa chọn tốt nếu bạn chủ yếu có ý định chụp ảnh màn hình # Captures will be PIL.Image in RGB mode d = d3dshot.create() d = d3dshot.create(capture_output="pil") Tuy nhiên, D3DShot khá linh hoạt. Khi môi trường của bạn đáp ứng một số nhóm yêu cầu tùy chọn nhất định, sẽ có nhiều tùy chọn hơn Nếu NumPy có sẵn 0Nếu NumPy và PyTorch khả dụng 1Nếu NumPy và PyTorch khả dụng + CUDA được cài đặt và đèn pin. cuda. is_available() 2Việc cố gắng sử dụng Đầu ra chụp mà môi trường của bạn không đáp ứng các yêu cầu sẽ dẫn đến lỗi Độc thânWindows chỉ cho phép 1 phiên bản Sao chép màn hình trên mỗi quy trình. Để đảm bảo rằng chúng tôi phù hợp với giới hạn đó để tránh các sự cố, lớp D3DShot hoạt động như một lớp đơn. Mọi lệnh gọi tiếp theo tới 7 sẽ luôn trả về phiên bản hiện có 3Khung đệmKhi bạn tạo một phiên bản D3DShot, bộ đệm khung cũng được khởi tạo. Nó có nghĩa là một cách an toàn theo luồng, nhập trước, xuất trước để giữ một số lượng ảnh chụp nhất định và được triển khai dưới dạng 8Theo mặc định, kích thước của bộ đệm khung được đặt thành 60. Bạn có thể tùy chỉnh nó khi tạo đối tượng D3DShot của mình 4Hãy chú ý đến việc sử dụng RAM với các giá trị lớn hơn; Bộ đệm khung có thể được truy cập trực tiếp bằng 9 nhưng thay vào đó, nên sử dụng các phương thức tiện íchBộ đệm được sử dụng theo các phương pháp sau
Nó luôn tự động bị xóa trước khi bắt đầu một trong các thao tác này Hiển thịKhi bạn tạo một phiên bản D3DShot, các màn hình khả dụng của bạn sẽ tự động được phát hiện cùng với tất cả các thuộc tính có liên quan của chúng 5_______2_______6Theo mặc định, màn hình chính của bạn sẽ được chọn. Tại mọi thời điểm, bạn có thể xác minh màn hình nào được đặt để sử dụng để chụp 7
Chọn một màn hình khác để chụp cũng đơn giản như đặt import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()2 thành một giá trị khác từ import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()3 9
Xoay và chia tỷ lệ màn hình được D3DShot phát hiện và xử lý cho bạn
VùngTất cả các phương pháp chụp (bao gồm cả ảnh chụp màn hình) chấp nhận một import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()4 kwarg tùy chọn. Giá trị dự kiến là một bộ số nguyên có độ dài 4 sẽ được cấu trúc như thế này import d3dshot d = d3dshot.create() d.screenshot_to_disk()1 Ví dụ: nếu bạn chỉ muốn chụp vùng 200px x 200px được bù 100px từ cả bên trái và trên cùng, bạn sẽ thực hiện import d3dshot d = d3dshot.create() d.screenshot_to_disk()2 Nếu bạn đang chụp màn hình được chia tỷ lệ, vùng sẽ được tính theo độ phân giải đầy đủ, không theo tỷ lệ Nếu bạn xem qua mã nguồn, bạn sẽ nhận thấy rằng việc cắt vùng xảy ra sau khi chụp toàn bộ màn hình. Điều đó có vẻ không tối ưu nhưng thử nghiệm đã cho thấy rằng sao chép một vùng của GPU D3D11Texture2D sang CPU đích D3D11Texture2D bằng CopySubresourceRegion chỉ nhanh hơn khi vùng đó rất nhỏ. Trên thực tế, không mất nhiều thời gian để các khu vực lớn hơn thực sự bắt đầu trở nên chậm hơn so với chụp toàn màn hình bằng phương pháp này. Để làm cho mọi thứ tồi tệ hơn, nó làm tăng thêm rất nhiều sự phức tạp bằng cách làm cho độ cao bề mặt không khớp với kích thước bộ đệm và xử lý các màn hình xoay khác nhau. Do đó, người ta quyết định rằng sẽ hợp lý hơn nếu gắn bó với CopyResource trong mọi trường hợp và cắt xén sau khi thực tế Cách sử dụngTạo một phiên bản D3DShot import d3dshot d = d3dshot.create() d.screenshot_to_disk()3 import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()5 chấp nhận 2 kwargs tùy chọn
KHÔNG nhập trực tiếp lớp D3DShot và cố gắng tự khởi tạo nó. Hàm trợ giúp import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()5 khởi tạo và xác thực rất nhiều thứ cho bạn ở hậu trường Khi bạn có một phiên bản D3DShot trong phạm vi, chúng ta có thể bắt đầu thực hiện mọi thứ với nó Liệt kê các màn hình được phát hiện 5Chọn một màn hình để chụp Màn hình chính của bạn được chọn theo mặc định nhưng nếu bạn có thiết lập nhiều màn hình, bạn có thể chọn một mục khác trong import d3dshot import time d = d3dshot.create() d.capture() time.sleep(5) # Capture is non-blocking so we wait explicitely d.stop() d.get_latest_frame()3 import d3dshot d = d3dshot.create() d.screenshot_to_disk()5 Chụp màn hình import d3dshot d = d3dshot.create() d.screenshot_to_disk()6 0 chấp nhận 1 kwarg tùy chọn
trả lại. Ảnh chụp màn hình có định dạng phù hợp với đầu ra chụp mà bạn đã chọn khi tạo đối tượng D3DShot của mình Chụp ảnh màn hình và lưu vào đĩa import d3dshot d = d3dshot.create() d.screenshot_to_disk()7 2 chấp nhận 3 kwargs tùy chọn
trả lại. Một chuỗi đại diện cho đường dẫn đầy đủ đến tệp hình ảnh đã lưu Chụp ảnh màn hình mỗi X giây import d3dshot d = d3dshot.create() d.screenshot_to_disk()8 Hoạt động này là luồng và không chặn. Nó sẽ tiếp tục chạy cho đến khi 7 được gọi. Ảnh chụp được đẩy vào bộ đệm khung 8 chấp nhận 1 kwarg tùy chọn
trả lại. Một giá trị boolean cho biết chuỗi chụp đã được bắt đầu hay chưa Chụp ảnh màn hình cứ sau X giây và lưu vào đĩa import d3dshot d = d3dshot.create() d.screenshot_to_disk()9 Hoạt động này là luồng và không chặn. Nó sẽ tiếp tục chạy cho đến khi 7 được gọiimport d3dshot import time d = d3dshot.create(capture_output="numpy") d.display = d.displays[1] d.capture() time.sleep(3) # Capture is non-blocking so we wait explicitely d.stop() frame_stack = d.get_frame_stack((0, 1, 2, 3), stack_dimension="last") frame_stack.shape1 chấp nhận 2 kwargs tùy chọn
trả lại. Một giá trị boolean cho biết chuỗi chụp đã được bắt đầu hay chưa Bắt đầu chụp màn hình tốc độ cao 0Hoạt động này là luồng và không chặn. Nó sẽ tiếp tục chạy cho đến khi 7 được gọi. Ảnh chụp được đẩy vào bộ đệm khungimport d3dshot import time d = d3dshot.create(capture_output="numpy") d.display = d.displays[1] d.capture() time.sleep(3) # Capture is non-blocking so we wait explicitely d.stop() frame_stack = d.get_frame_stack((0, 1, 2, 3), stack_dimension="last") frame_stack.shape5 chấp nhận 2 kwargs tùy chọn
trả lại. Một giá trị boolean cho biết chuỗi chụp đã được bắt đầu hay chưa Lấy khung hình mới nhất từ bộ đệm 1trả lại. Khung có định dạng phù hợp với đầu ra chụp mà bạn đã chọn khi tạo đối tượng D3DShot của mình Lấy một khung cụ thể từ bộ đệm 2trả lại. Khung có định dạng phù hợp với đầu ra chụp mà bạn đã chọn khi tạo đối tượng D3DShot của mình Lấy các khung cụ thể từ bộ đệm 3trả lại. Danh sách các khung có định dạng phù hợp với đầu ra chụp mà bạn đã chọn khi tạo đối tượng D3DShot của mình Lấy các khung cụ thể từ bộ đệm dưới dạng ngăn xếp 4Chỉ có tác dụng đối với đầu ra chụp NumPy và PyTorch import d3dshot import time d = d3dshot.create(capture_output="numpy") d.display = d.displays[1] d.capture() time.sleep(3) # Capture is non-blocking so we wait explicitely d.stop() frame_stack = d.get_frame_stack((0, 1, 2, 3), stack_dimension="last") frame_stack.shape8 chấp nhận 1 kwarg tùy chọn
trả lại. Một mảng duy nhất được xếp chồng lên nhau trên kích thước đã chỉ định với định dạng phù hợp với đầu ra chụp mà bạn đã chọn khi tạo đối tượng D3DShot của mình. Nếu đầu ra chụp không thể xếp chồng lên nhau, hãy trả về danh sách các khung Kết xuất bộ đệm khung vào đĩa Các tệp sẽ được đặt tên theo quy ước này. 5 5 1 chấp nhận 1 kwarg tùy chọn
trả lại. Không có Hiệu suấtViệc đo lường hiệu suất chính xác của Windows Desktop Duplication API tỏ ra hơi phức tạp vì nó sẽ chỉ trả về dữ liệu kết cấu mới nếu nội dung của màn hình đã thay đổi. Điều này là tối ưu cho hiệu suất nhưng lại gây khó khăn khi diễn đạt theo số khung hình trên giây, phép đo mà mọi người có xu hướng mong đợi đối với điểm chuẩn. Cuối cùng, giải pháp cuối cùng là chạy một trò chơi video FPS cao trên màn hình để chụp nhằm đảm bảo nội dung màn hình luôn khác nhau trong khi đo điểm chuẩn Như mọi khi, hãy nhớ rằng điểm chuẩn vốn có sai sót và phụ thuộc nhiều vào cấu hình phần cứng cá nhân của bạn và các trường hợp khác. Sử dụng các con số bên dưới như một dấu hiệu tương đối về những gì mong đợi từ D3DShot, không phải là một sự thật tuyệt đối nào đó 2560x1440 trên NVIDIA GTX 1080 Ti1920x1080 trên Intel UHD Graphics 6301080x1920 (dọc) trên Intel UHD Graphics 630"pil"29. 717FPS47. 75FPS35. 95 FPS"nặng nề"57. 667FPS58. 1FPS58. 033 FPS"numpy_float"18. 783FPS29. 05FPS27. 517 FPS"pytorch"57. 867FPS58. 1 FPS34. 817 FPS"pytorch_float"18. 767FPS28. 367FPS27. 017 FPS"pytorch_gpu"27. 333FPS35. 767FPS34. 8 khung hình/giây"pytorch_float_gpu"27. 267 FPS37. 383FPS35. 033FPSCác đầu ra chụp nhanh nhất tuyệt đối dường như là "pytorch" và không xoay được; . Ở vùng đất Python, đây là NHANH CHÓNG Hiệu suất đầu ra chụp "numpy" tốt như thế nào?Mảng NumPy có giao diện ctypes có thể cung cấp cho bạn địa chỉ bộ nhớ thô của chúng ( 3). Nếu bạn có địa chỉ bộ nhớ và kích thước của một bộ đệm byte khác, đó là những gì chúng tôi kết thúc bằng cách xử lý những gì trả về từ API Sao chép máy tính để bàn, bạn có thể sử dụng 4 để sao chép trực tiếp bộ đệm byte đó vào cấu trúc NumPy, bỏ qua Python một cách hiệu quả Trong thực tế, nó kết thúc như thế này 6Hoạt động cấp thấp này cực kỳ nhanh, bỏ lại mọi thứ khác thường cạnh tranh với NumPy trong bụi Tại sao đầu ra chụp "pytorch" chậm hơn trên màn hình được xoay?Đừng nói với ai nhưng lý do nó có thể cạnh tranh với NumPy ngay từ đầu chỉ vì. nó được tạo từ một mảng NumPy được xây dựng từ phương thức trên. Nếu bạn dò mã, bạn sẽ thực sự tìm thấy 5 nằm rải rác xung quanh. Điều này khá phù hợp với tốc độ của đầu ra chụp "numpy" 1. 1, ngoại trừ khi xử lý màn hình xoay. Xoay màn hình được xử lý bởi các cuộc gọi 6 mang lại những bước tiến tiêu cực trên mảng đó. Các bước tiến tiêu cực được hiểu và hoạt động tốt trong NumPy nhưng vẫn chưa được hỗ trợ trong PyTorch tại thời điểm viết. Để giải quyết vấn đề này, cần có một thao tác sao chép bổ sung để đưa nó trở lại một mảng liền kề, điều này sẽ áp đặt một hình phạt về hiệu suấtTại sao đầu ra chụp "pil", là mặc định, không phải là nhanh nhất?PIL không có giao diện ctypes như NumPy, do đó, một mảng phụ cần được đọc vào Python trước rồi sau đó được đưa vào 7. Điều này vẫn nhanh về mặt Python, nhưng nó không thể phù hợp với tốc độ của phương thức NumPy cấp thấpNó vẫn là đầu ra chụp mặc định vì
Tại sao các phiên bản float của đầu ra chụp chậm hơn?Dữ liệu của kết cấu Direct3D có thể truy cập được bằng Desktop Duplication API được định dạng dưới dạng byte. Thay vào đó, để biểu diễn dữ liệu này dưới dạng float được chuẩn hóa, cần thực hiện phép chia kiểu và phân chia theo phần tử trên mảng chứa các byte đó. Điều này áp đặt một hình phạt hiệu suất lớn. Thật thú vị, bạn có thể thấy hình phạt về hiệu suất này được giảm nhẹ trên các bộ kéo PyTorch của GPU do sự phân chia theo phần tử có thể được song song hóa trên diện rộng trên thiết bị Cách nhanh nhất để chụp ảnh màn hình là gì?Alt + Màn hình in
. Thao tác này sẽ chụp cửa sổ hiện đang hoạt động của bạn và sao chép ảnh chụp màn hình vào khay nhớ tạm. Bạn sẽ cần mở ảnh trong trình chỉnh sửa hình ảnh để lưu ảnh.
Chúng tôi có thể chụp ảnh màn hình bằng Python không?Phương pháp 1. Sử dụng mô-đun pyautogui
. Và sau đó, chức năng lưu được sử dụng để lưu ảnh chụp màn hình đã chụp vào thiết bị của chúng tôi. |