2012-03-17 37 views
7

Trong Photoshop, bạn có thể chọn "Color" (thứ hai từ dưới lên) để thiết lập chế độ hòa trộn cho layer thấp hơn tiếp theo:ảnh Draw trên đầu trang của hình ảnh khác với pha trộn chế độ màu

Layer blending mode selection photoshop

Nếu bạn chỉ có một gradient trên đỉnh của một hình ảnh kết quả có thể nhìn như thế này:

Color blending example

các mô tả về các chế độ màu pha trộn tôi thấy đâu đó là:

Màu sắc thay đổi màu sắc và độ bão hòa của lớp dưới thành màu và độ bão hòa của lớp trên nhưng chỉ để lại độ sáng.

Mã của tôi cho đến nay là:

using(var g = Graphics.FromImage(canvas)) 
{ 
    // draw the lower image 
    g.DrawImage(lowerImg, left, top); 

    // creating a gradient and draw on top 
    using (Brush brush = new LinearGradientBrush(new Rectangle(0, 0, canvasWidth, canvasHeight), Color.Violet, Color.Red, 20)) 
    { 
     g.FillRectangle(brush, 0, 0, canvasWidth, canvasHeight); 
    } 
} 

Nhưng đó là - tất nhiên - chỉ cần vẽ lên ảnh thấp hơn.

Vì vậy, câu hỏi là:

Làm thế nào tôi có thể rút ra một hình ảnh trên đầu trang của một hình ảnh bằng cách sử dụng chế độ hòa trộn "màu sắc" như có sẵn trong Photoshop?

EDIT:

Để làm cho nó rõ ràng hơn một chút về những gì tôi muốn đạt được:

enter image description here

Và nếu ai đó muốn sử dụng hình ảnh để thử nghiệm:

enter image description here enter image description here

+0

Bạn cần thực hiện một số phép tính màu. Tôi ước tôi có thời gian để làm điều đó và đăng câu trả lời, nhưng tôi xin lỗi! Có lẽ tối nay :) –

+0

Thats không phải là một vấn đề Tôi có rất nhiều thứ khác để làm và có thể chờ đợi cho điều này trong một ngày - vì vậy nếu bạn muốn, cảm thấy tự do để làm như vậy, sẽ rất tốt đẹp :) Tôi khá xấu/mới để xử lý hình ảnh. – Marc

+0

Chắc chắn! Tôi thích làm những việc như thế này;) –

Trả lời

6

Đây là giải pháp của tôi. Tôi đã sử dụng lớp HSLColor của Rich Newman để chuyển đổi giữa các giá trị RGB và HSL.

using (Bitmap lower = new Bitmap("lower.png")) 
using (Bitmap upper = new Bitmap("upper.png")) 
using (Bitmap output = new Bitmap(lower.Width, lower.Height)) 
{ 
    int width = lower.Width; 
    int height = lower.Height; 
    var rect = new Rectangle(0, 0, width, height); 

    BitmapData lowerData = lower.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
    BitmapData upperData = upper.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
    BitmapData outputData = output.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); 

    unsafe 
    { 
     byte* lowerPointer = (byte*) lowerData.Scan0; 
     byte* upperPointer = (byte*) upperData.Scan0; 
     byte* outputPointer = (byte*) outputData.Scan0; 

     for (int i = 0; i < height; i++) 
     { 
      for (int j = 0; j < width; j++) 
      { 
       HSLColor lowerColor = new HSLColor(lowerPointer[2], lowerPointer[1], lowerPointer[0]); 
       HSLColor upperColor = new HSLColor(upperPointer[2], upperPointer[1], upperPointer[0]); 
       upperColor.Luminosity = lowerColor.Luminosity; 
       Color outputColor = (Color) upperColor; 

       outputPointer[0] = outputColor.B; 
       outputPointer[1] = outputColor.G; 
       outputPointer[2] = outputColor.R; 

       // Moving the pointers by 3 bytes per pixel 
       lowerPointer += 3; 
       upperPointer += 3; 
       outputPointer += 3; 
      } 

      // Moving the pointers to the next pixel row 
      lowerPointer += lowerData.Stride - (width * 3); 
      upperPointer += upperData.Stride - (width * 3); 
      outputPointer += outputData.Stride - (width * 3); 
     } 
    } 

    lower.UnlockBits(lowerData); 
    upper.UnlockBits(upperData); 
    output.UnlockBits(outputData); 

    // Drawing the output image 
} 
+0

Tốt hơn câu trả lời tôi muốn đăng. Chỉ cần một số đánh bóng. Nó là tốt hơn để làm cho nó một phương pháp với giao diện được xác định. Và cũng có thể xem xét các tình huống cung cấp hình ảnh không cùng kích thước. –

+0

+1 và chấp nhận - Whoa, awesome, hoạt động như một sự quyến rũ! Cảm ơn rất nhiều! Tôi ước tôi có thể upvote 10 lần này! – Marc

0

Bạn sẽ phải cấu trúc lại mã của mình để vẽ gradient trên một bitmap tạm thời, đọc từng pixel từ bitmap và canvas tạm thời và viết pixel được tạo thành canvas. Bạn sẽ có thể tìm mã chuyển đổi giữa màu RGB và HSL, và một khi bạn có thể làm điều đó, thiết lập màu sắc và độ bão hòa của pixel trong canvas thành các giá trị từ bitmap tạm thời của bạn là tầm thường (mặc dù hơi khó hơn một chút nếu bạn muốn sử dụng giá trị alpha).

0

Đây là phiên bản an toàn (và chậm hơn) của câu trả lời được chấp nhận để hoàn thành.

 using (var lower = new Bitmap(@"lower.png")) 
     using (var upper = new Bitmap(@"upper.png")) 
     using (var output = new Bitmap(lower.Width, lower.Height)) 
     { 
      var width = lower.Width; 
      var height = lower.Height; 

      for (var i = 0; i < height; i++) 
      { 
       for (var j = 0; j < width; j++) 
       { 
        var upperPixel = upper.GetPixel(j, i); 
        var lowerPixel = lower.GetPixel(j, i); 

        var lowerColor = new HSLColor(lowerPixel.R, lowerPixel.G, lowerPixel.B); 
        var upperColor = new HSLColor(upperPixel.R, upperPixel.G, upperPixel.B) {Luminosity = lowerColor.Luminosity}; 
        var outputColor = (Color)upperColor; 

        output.SetPixel(j, i, outputColor); 
       } 
      } 

      // Drawing the output image 
     } 
Các vấn đề liên quan