/// <summary> /// Overlays pixel data from another <see cref="BitmapBuffer"/>, with alpha blending. /// </summary> /// <param name="x"> /// The x-coordinate where to begin writing in this <see cref="BitmapBuffer"/>.</param> /// <param name="y"> /// The y-coordinate where to begin writing in this <see cref="BitmapBuffer"/>.</param> /// <param name="source"> /// Another <see cref="BitmapBuffer"/> containing the rectangle to overlay.</param> /// <param name="bounds"> /// The pixel rectangle within the specified <paramref name="source"/> to overlay.</param> /// <param name="color"> /// The <see cref="Color"/> to substitute for all <paramref name="source"/> pixels.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="source"/> is a null reference.</exception> /// <remarks><para> /// <b>Overlay</b> blends all <see cref="Pixels"/> elements within the specified <paramref /// name="bounds"/> of the specified <paramref name="source"/> buffer with the corresponding /// <see cref="Pixels"/> elements in this <see cref="BitmapBuffer"/>, starting with the /// specified <paramref name="x"/> and <paramref name="y"/> coordinates. /// </para><para> /// <b>Overlay</b> calls <see cref="BitmapUtility.BlendPbgra32"/> to perform alpha blending /// between the specified <paramref name="source"/> buffer (acting as the overlay) and this /// <see cref="BitmapBuffer"/> (acting as the blending target). No coordinate checking is /// performed. /// </para><para> /// <b>Overlay</b> substitutes the specified <paramref name="color"/> for the actual color /// channels of each <paramref name="source"/> pixel, while using its alpha channel to /// govern alpha blending with the corresponding <see cref="Pixels"/> element. The alpha /// channel of the specified <paramref name="color"/> is ignored.</para></remarks> public void Overlay(int x, int y, BitmapBuffer source, RectI bounds, Color color) { if (source == null) { ThrowHelper.ThrowArgumentNullException("source"); } int sourceOffset = bounds.X + source._size.Width * bounds.Y; int targetOffset = x + _size.Width * y; for (int dy = 0; dy < bounds.Height; dy++) { for (int dx = 0; dx < bounds.Width; dx++) { uint p0 = source._pixels[sourceOffset + dx]; uint p1 = _pixels[targetOffset + dx]; // multiply color channels with source alpha color.A = (byte)(p0 >> 24); p0 = BitmapUtility.ColorToPbgra32(color); _pixels[targetOffset + dx] = BitmapUtility.BlendPbgra32(p0, p1); } sourceOffset += source._size.Width; targetOffset += _size.Width; } }
/// <summary> /// Blends the specified pixel in the <see cref="BitmapBuffer"/> with the specified <see /// cref="Color"/>.</summary> /// <param name="x"> /// The x-coordinate of the pixel to blend with <paramref name="color"/>.</param> /// <param name="y"> /// The y-coordinate of the pixel to blend with <paramref name="color"/>.</param> /// <param name="color"> /// The <see cref="Color"/> to blend with the pixel at the specified location in the <see /// cref="BitmapBuffer"/>.</param> /// <remarks><para> /// <b>BlendPixel</b> blends the <see cref="Pixels"/> element at the specified <paramref /// name="x"/> and <paramref name="y"/> coordinates with the <see /// cref="PixelFormats.Pbgra32"/> representation of the specified <paramref name="color"/>. /// </para><para> /// <b>BlendPixel</b> calls <see cref="BitmapUtility.BlendPbgra32"/> to perform alpha /// blending between the specified <paramref name="color"/> (acting as the overlay) and this /// <see cref="BitmapBuffer"/> (acting as the blending target). No coordinate checking is /// performed.</para></remarks> public void BlendPixel(int x, int y, Color color) { uint value = BitmapUtility.ColorToPbgra32(color); int i = x + _size.Width * y; _pixels[i] = BitmapUtility.BlendPbgra32(value, _pixels[i]); }
/// <overloads> /// Overlays pixel data from another <see cref="BitmapBuffer"/>.</overloads> /// <summary> /// Overlays pixel data from another <see cref="BitmapBuffer"/>, with alpha blending. /// </summary> /// <param name="x"> /// The x-coordinate where to begin writing in this <see cref="BitmapBuffer"/>.</param> /// <param name="y"> /// The y-coordinate where to begin writing in this <see cref="BitmapBuffer"/>.</param> /// <param name="source"> /// Another <see cref="BitmapBuffer"/> containing the rectangle to overlay.</param> /// <param name="bounds"> /// The pixel rectangle within the specified <paramref name="source"/> to overlay.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="source"/> is a null reference.</exception> /// <remarks><para> /// <b>Overlay</b> blends all <see cref="Pixels"/> elements within the specified <paramref /// name="bounds"/> of the specified <paramref name="source"/> buffer with the corresponding /// <see cref="Pixels"/> elements in this <see cref="BitmapBuffer"/>, starting with the /// specified <paramref name="x"/> and <paramref name="y"/> coordinates. /// </para><para> /// <b>Overlay</b> calls <see cref="BitmapUtility.BlendPbgra32"/> to perform alpha blending /// between the specified <paramref name="source"/> buffer (acting as the overlay) and this /// <see cref="BitmapBuffer"/> (acting as the blending target). No coordinate checking is /// performed.</para></remarks> public void Overlay(int x, int y, BitmapBuffer source, RectI bounds) { if (source == null) { ThrowHelper.ThrowArgumentNullException("source"); } int sourceOffset = bounds.X + source._size.Width * bounds.Y; int targetOffset = x + _size.Width * y; for (int dy = 0; dy < bounds.Height; dy++) { for (int dx = 0; dx < bounds.Width; dx++) { uint p0 = source._pixels[sourceOffset + dx]; uint p1 = _pixels[targetOffset + dx]; _pixels[targetOffset + dx] = BitmapUtility.BlendPbgra32(p0, p1); } sourceOffset += source._size.Width; targetOffset += _size.Width; } }
public void BlendPbgra32() { Assert.AreEqual(0x12345678, BitmapUtility.BlendPbgra32(0x00ABCDEF, 0x12345678)); Assert.AreEqual(0xFFABCDEF, BitmapUtility.BlendPbgra32(0xFFABCDEF, 0x12345678)); Assert.AreEqual(0xAF485058, BitmapUtility.BlendPbgra32(0x7F203040, 0x60504030)); }