2010-05-21 90 views
8

Tôi muốn thay thế tất cả các pixel trong vùng hình chữ nhật của một Bitmap bằng 'màu trắng trong suốt' - tức là, a = 0, b = 255, r = 255, g = 255.Làm thế nào để vẽ một khu vực của một bitmap với 'màu trắng trong suốt'?

FillRectangle không thực hiện điều này - với một bàn chải trong suốt, các pixel hiện tại không thay đổi.

Tôi có cần sử dụng riêng SetPixel cho mỗi pixel trong hình chữ nhật không?

Trả lời

13

Bạn sẽ phải đặt thuộc tính Graphics.CompositingMode. Ví dụ:

protected override void OnPaint(PaintEventArgs e) { 
    var img = Properties.Resources.Chrysanthemum; 
    e.Graphics.DrawImage(img, 0, 0); 
    e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; 
    using (var br = new SolidBrush(Color.FromArgb(0, 255, 255, 255))) { 
     e.Graphics.FillRectangle(br, new Rectangle(50, 50, 100, 100)); 
    } 
} 

Màu thực tế bạn sử dụng không quan trọng, bạn sẽ nhận được một hình chữ nhật màu đen với một alpha của 0.

+1

Nó không * không phổ biến để sử dụng kênh màu cho dữ liệu, nói cho một bản đồ địa hình trong một trò chơi nơi nước, đường, đá, tuyết là ARGB. Vì vậy, đôi khi bạn muốn có thể tạo bitmap với các giá trị RGB bằng không và alpha khác. –

+1

BTW màu trong trường hợp của tôi là có liên quan vì sau đó xử lý 'trộn' các khu vực trong suốt màu sắc với các khu vực màu sắc khác. – mackenir

0

FillRectangle không làm điều này - với một bàn chải trong suốt, các pixel hiện tại không thay đổi.

Làm cho tinh thần, vì bạn đang vẽ với độ mờ là 0%. :)

Giải pháp nhanh cho Kiểm soát sẽ là khóa màu. Bạn có thể đặt màu chính của điều khiển thành một màu cụ thể (nghĩa là màu đỏ tươi); tất cả các điểm ảnh có màu này sẽ được hiển thị trong suốt. (Nếu điều khiển hỗ trợ nó, tất nhiên.)

Điều đó, hoặc bitmap.MakeTransparent (màu) cho các mục đích chung. Vấn đề là, một lần nữa, màu sắc được chỉ định sẽ trong suốt, vì vậy bạn phải chọn một màu không tồn tại trong hình ảnh. (Có một ví dụ khác ở đây: http://msdn.microsoft.com/en-us/library/ms172507%28v=VS.80%29.aspx)

Chỉnh sửa: Cuối cùng, phương pháp LockBits() được đề cập trong các nhận xét khác có thể là những gì bạn tìm kiếm. Một khi bạn hiểu cách các giá trị chiều rộng và sải chân tương tác, thật dễ dàng để thao tác hình ảnh ở mức thấp nhất có thể. Dưới đây là ví dụ chung: http://www.bobpowell.net/lockingbits.htm Chỉ cần đảm bảo hình ảnh hỗ trợ độ trong suốt (xem PixelFormat), sau đó khóa hình ảnh bằng chế độ thích hợp (tức là PixelFormat.Format32bppArgb), lặp qua từng pixel, đọc byte, viết màu mới, v.v.

+0

Vâng, điều đó hoàn toàn có ý nghĩa :) Tôi chỉ là sayin. Khác hơn thế, tôi không nghĩ rằng câu trả lời của bạn là có liên quan - Tôi đang làm việc với một Bitmap, không phải là một điều khiển. Và mặc dù tôi có thể vẽ hình chữ nhật một màu đặc biệt (và hy vọng rằng màu đó không có mặt ở bất kỳ nơi nào khác trong hình ảnh) và sau đó làm cho nó trong suốt, tôi có thể chỉ định 'màu trắng trong suốt' không? Tôi không nghĩ vậy. – mackenir

+0

yourBitmap.MakeTransparent (Color.White) nên làm điều đó. Nhược điểm là tất cả mọi thứ màu trắng là trong suốt sau đó, đó là sự thật. Một vấn đề là không phải mọi định dạng ảnh đều hỗ trợ độ trong suốt, vì vậy nó cũng có thể phụ thuộc vào cách đối tượng hình ảnh của bạn được tạo ra. Hãy xem bảng liệt kê và thành viên của PixelFormat. Và sau đó, tất nhiên, cách tiếp cận để khóa bitmap hoạt động trong thứ nguyên con trỏ "không an toàn". Những gì Pete nói. :) – sunside

2

Nếu bạn sử dụng phương pháp vẽ hỗn hợp, thì alpha sẽ được sử dụng để pha trộn màu sắc, vì vậy sẽ không có gì xảy ra.

Nếu bạn muốn đặt bitmap, hãy tạo bitmap từ dữ liệu với nền bạn muốn hoặc đặt nền sử dụng LockBits để thao tác với dữ liệu.

Bạn cũng có thể thực hiện bằng cách sử dụng phương pháp bitblt với các cờ thích hợp, nhưng tôi không biết cách dịch mã đó thành mã được quản lý.

0

ít hack này nên làm như lừa:

Graphics g = Graphics.FromImage(myBitmap); 
g.SetClip(new RectangleF(10, 10, 20, 20)); 
g.Clear(Color.Transparent); 
g.RestoreClip(); 
g.Dispose(); 
+0

Không. Điều đó đặt pixel thành "màu đen trong suốt": 0,0,0,0, không phải là "màu trắng trong suốt": 0,255,255,255. – Guffa

+0

Bạn có thể đổi thành 'g.Clear (Color.FromArgb (0, 255, 255, 255)); ' Mặc dù câu trả lời của Hans Passant có lẽ tốt hơn –

3

Tôi tin rằng bạn cần phải sử dụng SetPixel (hoặc phương pháp tương đương với thiết lập các giá trị màu trực tiếp) để có được các điểm ảnh là "màu trắng trong suốt".

Bạn có thể sử dụng phương pháp Graphics.Clear để đặt màu hoặc pixel, nhưng bạn không thể sử dụng nó để đặt chúng thành màu trong suốt và màu. Tôi đã thử cách này để đặt pixel thành một phần của bitmap:

using (Graphics g = Graphics.FromImage(theBitmap)) { 
    g.Clip = new Region(new Rectangle(10, 10, 80, 80)); 
    g.Clear(Color.FromArgb(0, Color.White)); 
} 

Các pixel trong khu vực kết thúc là "đen trong suốt": 0,0,0,0. Ngay cả vẽ một hình chữ nhật màu trắng vững chắc trước khi thanh toán bù trừ không giúp đỡ. Khi alpha bằng 0, các thành phần màu khác cũng bằng không.

Sử dụng alpha gần như trong suốt như 1 hoạt động tốt, các điểm ảnh kết thúc là "màu trắng gần như trong suốt": 1,255,255,255.

1

mũi Chú ý:

Hãy chắc chắn rằng khi bạn tạo ra các hình ảnh mà bạn thực hiện điều này

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppARgb); 

và không

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppRgb); 

Nó sẽ giúp bạn tiết kiệm một số rắc rối. Đừng cho rằng 32 bit có nghĩa là kênh alpha ;-)

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