2010-03-29 33 views
8

GoalCách hiệu quả nhất để gửi hình ảnh qua xử lý

hình ảnh đèo được tạo ra bởi một quá trình một cách hiệu quả và với tốc độ rất cao để quá trình khác. Hai quy trình chạy trên cùng một máy và trên cùng một máy tính để bàn. Hệ điều hành có thể là WinXP, Vista và Win7.

Mô tả chi tiết

Quá trình đầu tiên là chỉ duy nhất cho việc kiểm soát các giao tiếp với một thiết bị mà tạo ra các hình ảnh. Những hình ảnh này có kích thước khoảng 500x300px và có thể được cập nhật lên tới vài trăm lần mỗi giây. Quá trình thứ hai cần những hình ảnh này để xử lý chúng. Quy trình đầu tiên sử dụng API của bên thứ ba để vẽ hình ảnh từ thiết bị đến HDC. HDC này phải được tôi cung cấp.

Lưu ý: Đã có kết nối mở giữa hai quy trình. Họ đang giao tiếp thông qua các đường ống ẩn danh và chia sẻ các khung nhìn tập tin được ánh xạ bộ nhớ.

Suy nghĩ

Làm thế nào tôi sẽ đạt được mục tiêu này với càng ít việc càng tốt? Và tôi có nghĩa là cả hai làm việc cho máy tính và tôi (tất nhiên;)). Tôi đang sử dụng Delphi, vì vậy có lẽ có một số thành phần có sẵn để làm điều này? Tôi nghĩ rằng tôi luôn có thể vẽ cho HDC của bất kỳ thành phần hình ảnh nào, lưu nội dung vào luồng bộ nhớ, sao chép nội dung qua tệp ánh xạ bộ nhớ, giải nén nó ở phía bên kia và tô nó vào HDC đích. Tôi cũng đọc về một giao diện IPicture có thể được sử dụng để sắp xếp hình ảnh. Tôi cần nó càng nhanh càng tốt, vì vậy chi phí càng ít càng tốt. Tôi không muốn máy bị căng thẳng chỉ bằng cách sao chép một số hình ảnh.

Ý tưởng của bạn là gì? Tôi đánh giá cao mọi suy nghĩ về điều này!

+1

nếu hình ảnh đang được cập nhật vài trăm lần mỗi giây, bạn có thể muốn xem xét bất kỳ kỹ thuật xử lý video hiện có nào để xử lý dữ liệu video băng thông cao thay vì xử lý hình ảnh. –

Trả lời

1

Ok có vẻ như các tập tin và đường dẫn ánh xạ bộ nhớ là cách phù hợp để thực hiện. Đó không phải là quá xấu bởi vì hai quá trình đã chia sẻ một MMF và hai ống (đối với truyền thông hai chiều). Điều duy nhất còn lại để giải quyết là làm thế nào để truyền dữ liệu với ít hoạt động sao chép nhất có thể.

Việc thiết kế mà hoạt động khá tốt trông như sau (tuần tự chảy):

Process 1 (muốn hình ảnh)

  • cho tín hiệu để xử lý 2 (thông qua ống 1) để lưu trữ hình ảnh trong bộ nhớ chia sẻ
  • đi ngủ và chờ đợi phản ứng (blocking đọc từ ống 2)

Process 2 (cung cấp hình ảnh)

  • trên tín hiệu (thông qua ống 1) thức dậy và nói với thiết bị phần cứng để sơn để HDC 1 (điều này được hỗ trợ bởi bộ nhớ chia sẻ, xem dưới đây)
  • cho tín hiệu để xử lý 1 (thông qua ống 2)
  • đi ngủ và chờ công việc mới (thông qua ống 1)

Process 1 (muốn hình ảnh)

  • trên tín hiệu (thông qua ống 2) thức dậy và sơn từ bộ nhớ chia sẻ đến đích HDC 2

Bây giờ cho việc chuyển ảnh qua bộ nhớ chia sẻ (mục tiêu của tôi là sử dụng không quá một thêm hoạt động sao chép):

Process 2 tạo ra một HBITMAP qua CreateDIBSection và cung cấp xử lý các tập tin bản đồ và bù đắp của chế độ xem được ánh xạ. Do đó dữ liệu hình ảnh sống trong bộ nhớ chia sẻ. Điều này tạo ra một HBITMAP được chọn vào HDC 1 (cũng được tạo bởi quá trình 2) và sẽ được sử dụng từ bây giờ trở đi theo quy trình 2.

Quy trình 1 sử dụng StretchDIBits với con trỏ đến bộ nhớ của bản đồ được ánh xạ (như được mô tả here). Điều này có vẻ là chức năng duy nhất để nhận bit từ bộ nhớ trực tiếp vào một HDC khác (trong trường hợp này là HDC 2). Các chức năng khác sẽ sao chép chúng trước vào bộ đệm trung gian trước khi bạn có thể chuyển chúng từ đó sang HDC cuối cùng.

Vì vậy, cuối cùng có vẻ như các bit cần thiết để được chuyển giao là khoảng hai lần nhiều như trong đầu. Nhưng tôi nghĩ rằng điều này là tốt như nó được trừ khi chia sẻ xử lý GDI giữa các quá trình sẽ là có thể.

Lưu ý: Tôi đã sử dụng đường ống thay vì tín hiệu vì tôi cũng cần chuyển một số dữ liệu bổ sung.

11

Sử dụng Memory Mapped File.

Để tham chiếu Delphi, hãy xem Memory-mapped Files in DelphiShared Memory in Delphi.

Để có cách tiếp cận linh hoạt hơn, bạn có thể xem bằng cách sử dụng đường ống hoặc gửi dữ liệu bitmap qua TCP. Điều này sẽ cho phép bạn phân phối dữ liệu hình ảnh giữa các nút dễ dàng hơn, nếu cần.

+0

Vâng, tôi có thể làm điều đó với một tệp ánh xạ bộ nhớ. Tôi vẫn sẽ phải vẽ hình ảnh cho HDC của tôi, sắp xếp lại hình ảnh cho MMF, đọc chúng một lần nữa ở phía bên kia và vẽ hình ảnh đến HDC cuối cùng. Có vẻ như 4 hoạt động sao chép mà trước đây chỉ được sử dụng 1. Vì vậy, tôi đang tìm kiếm một cách hiệu quả hơn. Nhưng nếu không có thì đây là cách tôi nghĩ. –

4

Sử dụng bộ nhớ dùng chung để chuyển dữ liệu hình ảnh và một thứ khác (tên ống, ổ cắm, ...) để phối hợp bàn giao.

3

Trong một số trường hợp, bạn có thể vượt qua các xử lý HBITMAP trên các quy trình. Tôi đã nhìn thấy nó được thực hiện trước khi (có, trên XP/Vista), và đã rất ngạc nhiên khi tất cả mọi người khác trong nhóm khi một trong những đồng nghiệp của tôi cho tôi thấy. Nếu bộ nhớ phục vụ cho tôi một cách chính xác, tôi tin rằng nó sẽ hoạt động nếu HBITMAP được cấp phát với một trong các hàm GDI (CreateBitmap, CreateCompatibleBitmap, CreateDIBitmap, ...) Các xử lý HBIMAP được tạo bởi LoadBitmap sẽ không hoạt động vì nó chỉ là trỏ đến tài nguyên trong proc.

Điều đó, và tôi nghĩ khi bạn chia sẻ HBITMAP cho quá trình khác, đừng cố gắng làm bất cứ điều gì đặc biệt với nó ngoài các hoạt động BitBlt bình thường.

Ít nhất đó là những gì tôi nhớ. Chúng tôi đã may mắn vì các thư viện đồ họa của chúng tôi đã được viết để quản lý tất cả các hình ảnh như HBITMAP.

YMMV

+0

+1 Sẽ không sử dụng nó, nhưng vẫn thú vị. –

+1

Điều này thực sự thú vị, mặc dù tôi cũng không thể sử dụng nó mà không có cảm giác xấu. Dường như việc vượt qua các xử lý GDI qua các quy trình là một chút giống như cờ bạc - nó không nên hoạt động, nhưng đôi khi nó có vẻ xảy ra. (Xem http://stackoverflow.com/questions/2499487/sharing-hdc-between-different-processes mà tôi đã hỏi về phương pháp này trước tiên, vì tôi hy vọng nó sẽ dễ dàng như vậy.) –

+0

Nhưng những gì về điều này: http://stackoverflow.com/a/2500975/893350 Tôi đã thử điều này và tôi nhận được "Một lỗi chung xảy ra trong GDI +." ErrCode: -2147467259 –

0

Như tôi đã có thể thấy điều này, bạn có hai lựa chọn:

  1. đèo chỉ hình ảnh tay cầm/con trỏ đến quá trình khác, vì vậy cả hai quá trình chỉ làm việc trên một tập hợp các hình ảnh.
  2. Sao chép nội dung hình ảnh sang quá trình khác và làm việc trên bản sao từ đó trở đi.

Cách tiếp cận nào là tốt nhất tùy thuộc vào thiết kế của bạn. Công cụ tốt nhất cho cả hai cách tiếp cận sẽ là "tệp ánh xạ bộ nhớ" hoặc "ống được đặt tên". Đây là nhanh nhất bạn có thể nhận được. Các tập tin được ánh xạ bộ nhớ có thể là hình thức nhanh nhất của giao tiếp giữa các quá trình nhưng có phần mềm không có mô hình "client-server" được xây dựng trong chúng. Vì vậy, bạn phải đồng bộ hóa các acces để MMF mình. Mặt khác, các đường ống được đặt tên gần như nhanh nhưng có mô hình máy khách-khách hàng xây dựng ngay vào chúng. Sự khác biệt về tốc độ chủ yếu đến từ đó.

Bây giờ vì tốc độ chia sẻ của bản cập nhật, cách tiếp cận đầu tiên có thể tốt hơn, nhưng sau đó bạn phải xem để đồng bộ hóa giữa các quy trình, vì vậy chúng không đọc/ghi vào cùng một hình ảnh. Ngoài ra một số loại bộ nhớ đệm hoặc tehniques thông minh khác có thể được sử dụng, vì vậy bạn giảm lưu lượng truy cập của bạn đến mức tối thiểu. Khi phải đối mặt với mức độ liên lạc cao như vậy, luôn luôn có thể tìm kiếm các phương tiện để giảm mức đó nếu có thể.

Để triển khai IPC nhanh chóng dựa trên các đường ống có tên, bạn có thể sử dụng triển khai IPC của mình. Đó là thông điệp được định hướng để bạn không phải lo lắng về chi tiết kỹ thuật đường ống. Nó cũng sử dụng hồ bơi thread đằng sau hậu trường và có chi phí bổ sung mininal. Bạn có thể nhấn mạnh kiểm tra nó và xem cho chính mình (một thông điệp điển hình mất 0,1 ms cho chu kỳ yêu cầu-đáp ứng đầy đủ máy chủ-máy khách).

+0

Cảm ơn bạn đã liên kết đến triển khai IPC của mình - có thể cần sau này nếu chúng tôi cần phải đi qua các ranh giới máy tính. Nhưng trường hợp sử dụng của tôi là rất hẹp ngay bây giờ. Tôi đã từng đọc rằng các miền khác nhau có thể gây rắc rối với các đường ống có tên, bạn đã thử nghiệm điều này chưa? –

+0

Tôi đã thử nghiệm trên hai máy tính trong cùng một mạng LAN, cùng một miền. Tôi không thử kết hợp khác. Tôi sử dụng nó để giao tiếp giữa các quá trình trên cùng một máy tính, vì nó dễ sử dụng hơn MMF. Không cần phải thực hiện bất kỳ đồng bộ hóa nào. – Runner

Các vấn đề liên quan