public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { int warmth = Data.Warmth; float redAdjust = 1.0f + (warmth / 100.0f); float blueAdjust = 1.0f - (warmth / 100.0f); this.blurEffect.Render(src, dest, rois); this.bacAdjustment.Render(src, dest, rois); foreach (Gdk.Rectangle roi in rois) { for (int y = roi.Top; y < roi.Bottom; ++y) { ColorBgra *srcPtr = src.GetPointAddress(roi.X, y); ColorBgra *dstPtr = dest.GetPointAddress(roi.X, y); for (int x = roi.Left; x < roi.Right; ++x) { ColorBgra srcGrey = this.desaturateOp.Apply(*srcPtr); srcGrey.R = Utility.ClampToByte((int)((float)srcGrey.R * redAdjust)); srcGrey.B = Utility.ClampToByte((int)((float)srcGrey.B * blueAdjust)); ColorBgra mypixel = this.overlayOp.Apply(srcGrey, *dstPtr); * dstPtr = mypixel; ++srcPtr; ++dstPtr; } } } }
/// <summary> /// Provides a default implementation for performing dst = F(dst, src) or F(src) over some rectangle /// of interest. May be slightly faster than calling the other multi-parameter Apply method, as less /// variables are used in the implementation, thus inducing less register pressure. /// </summary> /// <param name="dst">The Surface to write pixels to, and from which pixels are read and used as the lhs parameter for calling the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>.</param> /// <param name="dstOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the dst Surface.</param> /// <param name="src">The Surface to read pixels from for the rhs parameter given to the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>b>.</param></param> /// <param name="srcOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the src Surface.</param> /// <param name="roiSize">The size of the rectangles-of-interest for all Surfaces.</param> public void ApplyBase(ImageSurface dst, Gdk.Point dstOffset, ImageSurface src, Gdk.Point srcOffset, Gdk.Size roiSize) { // Create bounding rectangles for each Surface Gdk.Rectangle dstRect = new Gdk.Rectangle(dstOffset, roiSize); if (dstRect.Width == 0 || dstRect.Height == 0) { return; } Gdk.Rectangle srcRect = new Gdk.Rectangle(srcOffset, roiSize); if (srcRect.Width == 0 || srcRect.Height == 0) { return; } // Clip those rectangles to those Surface's bounding rectangles Gdk.Rectangle dstClip = Gdk.Rectangle.Intersect(dstRect, dst.GetBounds()); Gdk.Rectangle srcClip = Gdk.Rectangle.Intersect(srcRect, src.GetBounds()); // If any of those Rectangles actually got clipped, then throw an exception if (dstRect != dstClip) { throw new ArgumentOutOfRangeException ( "roiSize", "Destination roi out of bounds" + string.Format(", dst.Size=({0},{1}", dst.Width, dst.Height) + ", dst.Bounds=" + dst.GetBounds().ToString() + ", dstOffset=" + dstOffset.ToString() + string.Format(", src.Size=({0},{1}", src.Width, src.Height) + ", srcOffset=" + srcOffset.ToString() + ", roiSize=" + roiSize.ToString() + ", dstRect=" + dstRect.ToString() + ", dstClip=" + dstClip.ToString() + ", srcRect=" + srcRect.ToString() + ", srcClip=" + srcClip.ToString() ); } if (srcRect != srcClip) { throw new ArgumentOutOfRangeException("roiSize", "Source roi out of bounds"); } // Cache the width and height properties int width = roiSize.Width; int height = roiSize.Height; // Do the work. unsafe { for (int row = 0; row < height; ++row) { ColorBgra *dstPtr = dst.GetPointAddress(dstOffset.X, dstOffset.Y + row); ColorBgra *srcPtr = src.GetPointAddress(srcOffset.X, srcOffset.Y + row); Apply(dstPtr, srcPtr, width); } } }
private unsafe void ApplyRectangle(ImageSurface surface, Gdk.Rectangle rect) { for (int y = rect.Left; y <= rect.GetBottom(); ++y) { ColorBgra *ptr = surface.GetPointAddress(rect.Left, y); Apply(ptr, rect.Width); } }
public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { // Glow backgound glowEffect.Data.Radius = 6; glowEffect.Data.Brightness = -(Data.Coloring - 50) * 2; glowEffect.Data.Contrast = -(Data.Coloring - 50) * 2; this.glowEffect.Render(src, dest, rois); // Create black outlines by finding the edges of objects foreach (Gdk.Rectangle roi in rois) { for (int y = roi.Top; y < roi.Bottom; ++y) { int top = y - radius; int bottom = y + radius + 1; if (top < 0) { top = 0; } if (bottom > dest.Height) { bottom = dest.Height; } ColorBgra *srcPtr = src.GetPointAddress(roi.X, y); ColorBgra *dstPtr = dest.GetPointAddress(roi.X, y); for (int x = roi.Left; x < roi.Right; ++x) { int left = x - radius; int right = x + radius + 1; if (left < 0) { left = 0; } if (right > dest.Width) { right = dest.Width; } int r = 0; int g = 0; int b = 0; int src_width = src.Width; ColorBgra *src_dataptr = (ColorBgra *)src.DataPtr; for (int v = top; v < bottom; v++) { ColorBgra *pRow = src.GetRowAddressUnchecked(src_dataptr, src_width, v); int j = v - y + radius; for (int u = left; u < right; u++) { int i1 = u - x + radius; int w = conv[j][i1]; ColorBgra *pRef = pRow + u; r += pRef->R * w; g += pRef->G * w; b += pRef->B * w; } } ColorBgra topLayer = ColorBgra.FromBgr( Utility.ClampToByte(b), Utility.ClampToByte(g), Utility.ClampToByte(r)); // Desaturate topLayer = this.desaturateOp.Apply(topLayer); // Adjust Brightness and Contrast if (topLayer.R > (Data.InkOutline * 255 / 100)) { topLayer = ColorBgra.FromBgra(255, 255, 255, topLayer.A); } else { topLayer = ColorBgra.FromBgra(0, 0, 0, topLayer.A); } // Change Blend Mode to Darken ColorBgra myPixel = this.darkenOp.Apply(topLayer, *dstPtr); * dstPtr = myPixel; ++srcPtr; ++dstPtr; } } } }
public override void Apply(ImageSurface dst, Gdk.Point dstOffset, ImageSurface src, Gdk.Point srcOffset, int scanLength) { Apply(dst.GetPointAddress(dstOffset), src.GetPointAddress(srcOffset), scanLength); }
unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { int width = src.Width; int height = src.Height; int r = Data.Amount; Random localRandom = this.random; int * intensityCount = stackalloc int[256]; uint *avgRed = stackalloc uint[256]; uint *avgGreen = stackalloc uint[256]; uint *avgBlue = stackalloc uint[256]; uint *avgAlpha = stackalloc uint[256]; byte *intensityChoices = stackalloc byte[(1 + (r * 2)) * (1 + (r * 2))]; int src_width = src.Width; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (var rect in rois) { int rectTop = rect.Top; int rectBottom = rect.GetBottom(); int rectLeft = rect.Left; int rectRight = rect.GetRight(); for (int y = rectTop; y <= rectBottom; ++y) { ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y); int top = y - r; int bottom = y + r + 1; if (top < 0) { top = 0; } if (bottom > height) { bottom = height; } for (int x = rectLeft; x <= rectRight; ++x) { int intensityChoicesIndex = 0; for (int i = 0; i < 256; ++i) { intensityCount[i] = 0; avgRed[i] = 0; avgGreen[i] = 0; avgBlue[i] = 0; avgAlpha[i] = 0; } int left = x - r; int right = x + r + 1; if (left < 0) { left = 0; } if (right > width) { right = width; } for (int j = top; j < bottom; ++j) { if (j < 0 || j >= height) { continue; } ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, left, j); for (int i = left; i < right; ++i) { byte intensity = srcPtr->GetIntensityByte(); intensityChoices[intensityChoicesIndex] = intensity; ++intensityChoicesIndex; ++intensityCount[intensity]; avgRed[intensity] += srcPtr->R; avgGreen[intensity] += srcPtr->G; avgBlue[intensity] += srcPtr->B; avgAlpha[intensity] += srcPtr->A; ++srcPtr; } } int randNum; lock (localRandom) { randNum = localRandom.Next(intensityChoicesIndex); } byte chosenIntensity = intensityChoices[randNum]; byte R = (byte)(avgRed[chosenIntensity] / intensityCount[chosenIntensity]); byte G = (byte)(avgGreen[chosenIntensity] / intensityCount[chosenIntensity]); byte B = (byte)(avgBlue[chosenIntensity] / intensityCount[chosenIntensity]); byte A = (byte)(avgAlpha[chosenIntensity] / intensityCount[chosenIntensity]); *dstPtr = ColorBgra.FromBgra(B, G, R, A); ++dstPtr; // prepare the array for the next loop iteration for (int i = 0; i < intensityChoicesIndex; ++i) { intensityChoices[i] = 0; } } } } }
public static unsafe ColorBgra *GetPointAddress(this ImageSurface surf, Gdk.Point point) { return(surf.GetPointAddress(point.X, point.Y)); }
unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { double[,] weights = Weights; var srcWidth = src.Width; var srcHeight = src.Height; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (var rect in rois) { // loop through each line of target rectangle for (int y = rect.Top; y < rect.Bottom; ++y) { int fyStart = 0; int fyEnd = 3; if (y == 0) { fyStart = 1; } if (y == srcHeight - 1) { fyEnd = 2; } // loop through each point in the line ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { int fxStart = 0; int fxEnd = 3; if (x == 0) { fxStart = 1; } if (x == srcWidth - 1) { fxEnd = 2; } // loop through each weight double sum = 0.0; for (int fy = fyStart; fy < fyEnd; ++fy) { for (int fx = fxStart; fx < fxEnd; ++fx) { double weight = weights[fy, fx]; ColorBgra c = src.GetPointUnchecked(src_data_ptr, srcWidth, x - 1 + fx, y - 1 + fy); double intensity = (double)c.GetIntensityByte(); sum += weight * intensity; } } int iSum = (int)sum; iSum += 128; if (iSum > 255) { iSum = 255; } if (iSum < 0) { iSum = 0; } *dstPtr = ColorBgra.FromBgra((byte)iSum, (byte)iSum, (byte)iSum, 255); ++dstPtr; } } } }
unsafe public void Render(ImageSurface surface, Gdk.Rectangle[] rois) { byte startAlpha; byte endAlpha; if (this.alphaOnly) { ComputeAlphaOnlyValuesFromColors(this.startColor, this.endColor, out startAlpha, out endAlpha); } else { startAlpha = this.startColor.A; endAlpha = this.endColor.A; } surface.Flush(); ColorBgra *src_data_ptr = (ColorBgra *)surface.DataPtr; int src_width = surface.Width; for (int ri = 0; ri < rois.Length; ++ri) { Gdk.Rectangle rect = rois[ri]; if (this.startPoint.X == this.endPoint.X && this.startPoint.Y == this.endPoint.Y) { // Start and End point are the same ... fill with solid color. for (int y = rect.Top; y <= rect.GetBottom(); ++y) { ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y); for (int x = rect.Left; x <= rect.GetRight(); ++x) { ColorBgra result; if (this.alphaOnly && this.alphaBlending) { byte resultAlpha = (byte)Utility.FastDivideShortByByte((ushort)(pixelPtr->A * endAlpha), 255); result = *pixelPtr; result.A = resultAlpha; } else if (this.alphaOnly && !this.alphaBlending) { result = *pixelPtr; result.A = endAlpha; } else if (!this.alphaOnly && this.alphaBlending) { result = this.normalBlendOp.Apply(*pixelPtr, this.endColor); //if (!this.alphaOnly && !this.alphaBlending) } else { result = this.endColor; } *pixelPtr = result; ++pixelPtr; } } } else { var mainrect = rect; Parallel.ForEach(Enumerable.Range(rect.Top, rect.Height), (y) => ProcessGradientLine(startAlpha, endAlpha, y, mainrect, surface, src_data_ptr, src_width)); } } surface.MarkDirty(); AfterRender(); }