2008-12-29 37 views
6

Tôi có hai bitmap, được tạo bởi các biến thể khác nhau của thuật toán. Tôi muốn tạo một bitmap thứ ba bằng cách trừ một bitmap kia để hiển thị sự khác biệt.Làm thế nào để trừ một bitmap từ một bitmap khác trong C# /. NET?

Làm cách nào để thực hiện điều này trong .NET? Tôi đã xem qua lớp Graphics và tất cả các tùy chọn của nó, bao gồm lớp ImageAttributes, và tôi có một linh cảm nó liên quan đến ma trận màu hoặc chức năng remap của bảng.

Có ai có liên kết đến một số mã mẫu hay chỉ cho tôi đúng hướng không? Một tìm kiếm google không tiết lộ nhiều, trừ khi google-fu của tôi không làm tôi ngày hôm nay.

Trả lời

7

Câu hỏi thực sự là, bạn muốn hiển thị sự khác biệt nào? Nếu bạn chỉ cần vận hành trên các giá trị màu RGB, thì tốt nhất là bạn chỉ cần quét qua cả bitmap và so sánh các giá trị Color bằng cách sử dụng GetPixel, và sử dụng SetPixel để tạo bitmap 'khác biệt' của bạn. Có lẽ bạn chỉ muốn trừ các giá trị và sử dụng các giá trị đó làm giá trị Màu mới cho bitmap thứ ba. Hoặc có lẽ bạn muốn tính toán độ sáng và sử dụng nó. Thậm chí tốt hơn, nếu bạn có ba chỉ số để so sánh, hãy chỉ định từng số liệu cho các thành phần R G và B của màu sắc. Tôi đã sử dụng cách tiếp cận này để tô màu trước đây.

Có các cách tiếp cận khác, nhưng với phương pháp này, bạn chỉ bị giới hạn trong trí tưởng tượng của mình. Nó có thể không phải là cách tiếp cận nhanh nhất, nhưng nó không có vẻ như hiệu suất là cần thiết cho kịch bản này.

+0

Bạn nói đúng, hiệu suất không phải là nbr. 1 mục tiêu ở đây, và tôi càng nghĩ nhiều về nó, có vẻ như tôi chỉ cần tự viết mã. Ban đầu tôi đã nghĩ về một thuật toán đảo ngược-image2-add-to-image1, nhưng làm thế nào nó sẽ đối phó với kết quả tiêu cực ... ok, quay lại làm việc rồi :) –

+0

Nếu bạn cần hiệu suất, hãy nhớ rằng bạn có thể sử dụng phương thức LockBits của đối tượng Bitmap để nhận một mảng byte của các giá trị pixel thô, mà bạn có thể hoạt động. Có xu hướng nhanh hơn rất nhiều so với GetPixel và SetPixel. – driis

3

Kiểm tra dự án này. Nó là một máy dò chuyển động được thực hiện bởi Andrew Kirillov. Ông thực hiện một vài bộ lọc để có được sự khác biệt giữa hai hình ảnh và sử dụng để tính toán chuyển động. Nó thực sự tốt đẹp được thực hiện và dễ dàng để sửa đổi và sử dụng trong ứng dụng của riêng bạn.

http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx

+0

đó là một ví dụ thực sự tốt đẹp –

1

Thứ nhất, xác định trừ ;-p Những gì bạn muốn câu trả lời để tìm như thế nào?

Cách hiệu quả nhất để thực hiện điều này có thể là LockBits - nó sẽ nhanh hơn rất nhiều so với các cuộc gọi GetPixel, nhưng bạn sẽ cần phải tự giải mã các byte. Dễ dàng nếu nó chỉ là một cái gì đó giống như 32bpp ARGB, nhưng khó khăn cho một số trường hợp phức tạp hơn.

0

Tôi đã đọc ở đâu đó rằng ngôn ngữ được sử dụng trong Adobe Pixel Bender được lấy cảm hứng từ một cái gì đó mà Microsoft đã từng làm. Đừng nhớ nơi tôi đọc nó. Suy nghĩ của tôi là có lẽ Microsoft "một cái gì đó" được gói vào một cái gì đó mà một dự án Net có thể sử dụng. Overkill cho chỉ trừ hai hình ảnh, nhưng anyway.

2

Điều này có thể được thực hiện bằng cách PInvoking chức năng API BitBlt API. Dưới đây là một số mẫu mã:

http://www.codeproject.com/KB/GDI-plus/Bitblt_wrapper_class.aspx

Các mẫu sử dụng mã SRCCOPY raster op; để có được sự khác biệt giữa hai bitmap, thay vào đó bạn muốn sử dụng SRCPAINT hoặc một cái gì đó (GOOGLE nên cung cấp danh sách mã).

GetPixel và SetPixel (trên lớp Bitmap) không thể tin được chậm. Sử dụng LockBits sẽ nhanh hơn nhiều, nhưng bạn vẫn sẽ phải viết mã của riêng bạn.

Cập nhật: đây là một liên kết tốt hơn:

http://www.pinvoke.net/default.aspx/gdi32.BitBlt

và bao gồm tất cả các hoạt động raster ternary thể (SRCPAINT hoặc SRCAND có lẽ những gì bạn đang tìm kiếm.).

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