c# – 使用混合模式颜色在另一个图像上绘制图像

前端之家收集整理的这篇文章主要介绍了c# – 使用混合模式颜色在另一个图像上绘制图像前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在Photoshop中,您可以选择“颜色”(从底部开始的第二个)将混合模式设置为下一个较低层:

如果图像顶部只有一个渐变,结果可能如下所示:

我在某处找到的颜色混合模式的描述是:

颜色将下层的色调和饱和度改变为上层的色调和饱和度,但仅留下亮度.

到目前为止我的代码是:

  1. using(var g = Graphics.FromImage(canvas))
  2. {
  3. // draw the lower image
  4. g.DrawImage(lowerImg,left,top);
  5.  
  6. // creating a gradient and draw on top
  7. using (Brush brush = new LinearGradientBrush(new Rectangle(0,canvasWidth,canvasHeight),Color.Violet,Color.Red,20))
  8. {
  9. g.FillRectangle(brush,canvasHeight);
  10. }
  11. }

但那是 – 当然 – 只是在较低的图像上绘画.

所以问题是:

如何使用Photoshop中提供的混合模式“颜色”在另一个图像上绘制图像?

编辑:

为了使我更清楚我想要实现的目标:

如果有人想使用图像进行测试:

解决方法

这是我的解决方案.我使用Rich Newman的 HSLColor类来转换RGB和HSL值.
  1. using (Bitmap lower = new Bitmap("lower.png"))
  2. using (Bitmap upper = new Bitmap("upper.png"))
  3. using (Bitmap output = new Bitmap(lower.Width,lower.Height))
  4. {
  5. int width = lower.Width;
  6. int height = lower.Height;
  7. var rect = new Rectangle(0,width,height);
  8.  
  9. BitmapData lowerData = lower.LockBits(rect,ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
  10. BitmapData upperData = upper.LockBits(rect,PixelFormat.Format24bppRgb);
  11. BitmapData outputData = output.LockBits(rect,ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
  12.  
  13. unsafe
  14. {
  15. byte* lowerPointer = (byte*) lowerData.Scan0;
  16. byte* upperPointer = (byte*) upperData.Scan0;
  17. byte* outputPointer = (byte*) outputData.Scan0;
  18.  
  19. for (int i = 0; i < height; i++)
  20. {
  21. for (int j = 0; j < width; j++)
  22. {
  23. HSLColor lowerColor = new HSLColor(lowerPointer[2],lowerPointer[1],lowerPointer[0]);
  24. HSLColor upperColor = new HSLColor(upperPointer[2],upperPointer[1],upperPointer[0]);
  25. upperColor.Luminosity = lowerColor.Luminosity;
  26. Color outputColor = (Color) upperColor;
  27.  
  28. outputPointer[0] = outputColor.B;
  29. outputPointer[1] = outputColor.G;
  30. outputPointer[2] = outputColor.R;
  31.  
  32. // Moving the pointers by 3 bytes per pixel
  33. lowerPointer += 3;
  34. upperPointer += 3;
  35. outputPointer += 3;
  36. }
  37.  
  38. // Moving the pointers to the next pixel row
  39. lowerPointer += lowerData.Stride - (width * 3);
  40. upperPointer += upperData.Stride - (width * 3);
  41. outputPointer += outputData.Stride - (width * 3);
  42. }
  43. }
  44.  
  45. lower.UnlockBits(lowerData);
  46. upper.UnlockBits(upperData);
  47. output.UnlockBits(outputData);
  48.  
  49. // Drawing the output image
  50. }

猜你在找的C#相关文章