2010-08-15 29 views
10

Tôi khá mới đối với C# và đang cố gắng thực hiện một phần mềm xử lý hình ảnh cơ bản. Tôi hiểu đoạn trích này trích xuất A, R, G, B từ giá trị int ARGB của một WriteableBitmap pixel "hiện tại"Nhà điều hành >> làm gì trong C#?

for(int i = 0; i < bitmapArray.Length; i++) { 
    var current = bitmapArray[i]; 

    var alpha = (byte)(current >> 24); 
    var red = (byte)(current >> 16); 
    var green = (byte)(current >> 8); 
    var blue = (byte)(current); 
    //Some code 
} 

">>" đang làm gì để chuyển đổi các giá trị?

Ngoài ra, nếu tôi thực hiện một số phép tính cho r, g và b riêng lẻ, làm cách nào để chuyển đổi chúng trở lại giá trị ARGB nguyên để thay thế pixel ban đầu bằng pixel mới?

Xin cảm ơn trước.

Chỉnh sửa: cảm ơn các bạn, điều đó có ý nghĩa ngay bây giờ.

+0

Thực sự khá khó chịu khi cấu trúc 'Color' trong Silverlight không cung cấp phương tiện chuyển đổi' Int32' thành 'Color'. – AnthonyWJones

Trả lời

12

Nó đang dịch chuyển các bit của giá trị current sang phải. Trong trường hợp đoạn mã cụ thể này, nó dường như trích xuất từng byte thông tin màu từ phần tử mảng bitmap đã chọn thành các byte màu riêng lẻ.

http://msdn.microsoft.com/en-us/library/xt18et0d.aspx

Giả sử rằng mảng của bạn có chứa ints, để có được một giá trị tính toán lại vào phần tử mảng, bạn sẽ đảo ngược quá trình bit chuyển và OR kết quả trở lại với nhau, như vậy:

int current = (alpha << 24) | (red << 16) | (green << 8) | blue; 
+0

Tôi tự hỏi ... là 'BitConverter.GetBytes (hiện tại)' quá phức tạp? Hm, có lẽ quá chậm để thao tác hình ảnh nghiêm túc. – Joey

+0

@Johannes: 'BitConverter' rất nhanh. Tôi sẽ tưởng tượng nó sẽ thích hợp ở đây. –

+1

Đó là một hoạt động đơn giản, rõ ràng và phổ biến mà tôi không thấy lợi thế khi sử dụng bất kỳ thứ gì trừ các toán tử nhị phân.Nếu bạn không hiểu điều gì đang diễn ra, bạn nên học hoặc tránh xa việc xử lý hình ảnh (không phải là 'bạn' nói riêng), chỉ cần nói chung) –

16

Đây là toán tử dịch chuyển nhị phân.

Nếu bạn có một màu xác định bởi (a, r, g, b), đó là biểu diễn nhị phân sẽ trông như thế này (giả sử độ sâu kênh 8 bit):

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB 

Vì vậy, chuyển toàn bộ mà điều trên 24 địa điểm và các bạn là trái với các kênh alpha

AAAAAAAA 

phím Shift bằng 16 và bạn sẽ có được các kênh alpha và kênh màu đỏ

AAAAAAAARRRRRRRR 

Bây giờ, vì đó là vai một byte, chỉ có 8 bit đầu tiên được chiết xuất

(byte)AAAAAAAARRRRRRRR == RRRRRRRR 

Bạn cũng có thể nhận được các kênh màu đỏ bằng cách chuyển 16 nơi và AND'ing với 11111111 (0xFF)

AAAAAAAARRRRRRRR & 
0000000011111111 
---------------- 
00000000RRRRRRRR 
+1

+1. Đây là một lời giải thích tuyệt vời, tôi luôn tự hỏi về sự dịch chuyển bit và cách nó hoạt động. Nếu bạn có thời gian, nó sẽ là tuyệt vời để xem một ví dụ về cách làm như trên thay đổi một giá trị màu sắc và làm thế nào. Giống như cách bit dịch chuyển thay đổi 128, 64, 256 thành một số giá trị RGB khác. Ngoài ra, tôi vẫn không cam kết '(byte) AAAAAAAARRRRRRRR == RRRRRRRR' (tức là nó được trích xuất từ ​​phải sang trái?), Nhưng ít nhất tôi biết nhiều hơn tôi đã làm trước khi truy cập câu trả lời này. –

+0

@Otaku: Nhị phân được đọc từ phải sang trái và trong trường hợp này, "8 bit đầu tiên" có nghĩa là chỉ vậy. – junkforce

+0

Nếu bạn cast (pixel & 0xff000000) vào một byte, bạn sẽ nhận được một số không có vấn đề gì vì 8 bit ngoài cùng bên phải sẽ là 0. Vì vậy, tôi không nghĩ rằng khối cuối cùng của bạn là chính xác. – Jacob

2

tiếp tục đến câu trả lời của Robert - và để trang trải phần thứ hai của câu hỏi của bạn - bạn có thể kết hợp các thành phần riêng biệt về một số nguyên bằng cách sử dụng << (left-shift)| (bitwise OR) nhà khai thác:

int combined = (alpha << 24) | (red << 16) | (green << 8) | blue; 
+0

@ Robert: OP không chỉ định, và tôi cho rằng triết học không phải là - nó chỉ là một tập hợp 4 octet chưa ký. Nếu * cơ chế lưu trữ * là một 'int' thì mã của tôi sẽ hoạt động tốt (và kết quả sẽ là một' int' âm nếu giá trị alpha lớn hơn 127). Nếu cơ chế lưu trữ là 'uint' thì cần thêm một số phép đúc bổ sung. – LukeH

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