void Render(Surface dst, Surface src, Rectangle rect) { Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); ColorBgra sourcePixel, puzzlePixel, finalPixel; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { int offsetX = (int)(x + selection.Width * Amount5.First / 2); int offsetY = (int)(y + selection.Height * Amount5.Second / 2); puzzlePixel = GetBilinearSampleMirrored(puzzleSurface, offsetX - selection.Left, offsetY - selection.Top); sourcePixel = src[x, y]; if (Amount3) { sourcePixel.A = Int32Util.ClampToByte(255 - puzzlePixel.A); finalPixel = sourcePixel; } else { finalPixel = normalOp.Apply(sourcePixel, puzzlePixel); } dst[x, y] = finalPixel; } } }
private void Render(Surface dst, Surface src, Rectangle rect) { ColorBgra currentPixel; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { if ((horLoops > 1 || verLoops > 1) && !puzzleRect.Contains(x, y)) { currentPixel = src[x, y]; currentPixel.A = 0; // Delete pixels outside the puzzle border } else if (transparent) { currentPixel = src[x, y]; currentPixel.A = Int32Util.ClampToByte(byte.MaxValue - puzzleSurface[x, y].A); } else { currentPixel = normalOp.Apply(src[x, y], puzzleSurface[x, y]); } dst[x, y] = currentPixel; } } }
private void Render(Surface dst, Surface src, Rectangle rect) { if (blur != 0) { // Call the Gaussian Blur function blurEffect.Render(new Rectangle[] { rect }, 0, 1); } else { dst.CopySurface(shadowSurface, rect.Location, rect); } Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); Rectangle shadowRect = Rectangle.FromLTRB( selection.Left + margin + offsetX, selection.Top + margin + offsetY, selection.Right - margin + offsetX, selection.Bottom - margin + offsetY); ColorBgra shadowPixel; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { shadowPixel = dst[x, y]; shadowPixel.A = shadowRect.Contains(x, y) ? Int32Util.ClampToByte(shadowPixel.A * color.A / byte.MaxValue) : byte.MinValue; dst[x, y] = normalOp.Apply(src[x, y], shadowPixel); } } }
private void Render(Surface dst, Surface src, Rectangle rect) { ColorBgra currentPixel; // create point for testing how each pixel should be colored System.Windows.Point pointToTest = new System.Windows.Point(); for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { // update point's coordinates pointToTest.X = x; pointToTest.Y = y; currentPixel = src[x, y]; if (!this.marginBounds.Contains(x, y)) { currentPixel.A = byte.MinValue; } // if point is Not outside of the radius, use original source pixel Alpha value else if (!PointOutsideRadius(pointToTest, 0)) { // Do nothing. Alpha channel stays the same } else if (this.antiAlias) { if (!PointOutsideRadius(pointToTest, 0.333)) { currentPixel.A = (byte)(0.7 * currentPixel.A); } else if (!PointOutsideRadius(pointToTest, 0.666)) { currentPixel.A = (byte)(0.4 * currentPixel.A); } else if (!PointOutsideRadius(pointToTest, 1)) { currentPixel.A = (byte)(0.2 * currentPixel.A); } else { currentPixel.A = byte.MinValue; } } else { currentPixel.A = byte.MinValue; } dst[x, y] = (this.transparent) ? currentPixel : normalOp.Apply(this.backColor, currentPixel); } } }
// Draws a point, but first intersects it with the selection private void DrawPoint(RenderArgs ra, Point p, ColorBgra color) { if (ra.Surface.Bounds.Contains(p)) { if (ra.Graphics.IsVisible(p)) { BinaryPixelOp op = AppEnvironment.AlphaBlending ? blendOp : copyOp; ra.Surface[p.X, p.Y] = op.Apply(ra.Surface[p.X, p.Y], color); } } }
private unsafe bool ProcessGradientLine(byte startAlpha, byte endAlpha, int y, Rectangle rect, ISurface surface) { var pixelPtr = surface.GetPointAddress(rect.Left, y); var right = rect.Right; if (AlphaOnly && AlphaBlending) { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpAlpha = lerpAlphas[lerpByte]; var resultAlpha = Utility.FastScaleByteByByte(pixelPtr->A, lerpAlpha); pixelPtr->A = resultAlpha; ++pixelPtr; } } else if (AlphaOnly && !AlphaBlending) { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpAlpha = lerpAlphas[lerpByte]; pixelPtr->A = lerpAlpha; ++pixelPtr; } } else if (!AlphaOnly && (AlphaBlending && (startAlpha != 255 || endAlpha != 255))) { // If we're doing all color channels, and we're doing alpha blending, and if alpha blending is necessary for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpColor = lerpColors[lerpByte]; var result = normalBlendOp.Apply((*pixelPtr), lerpColor); * pixelPtr = result; ++pixelPtr; } //if (!this.alphaOnly && !this.alphaBlending) // or sC.A == 255 && eC.A == 255 } else { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpColor = lerpColors[lerpByte]; * pixelPtr = lerpColor; ++pixelPtr; } } return(true); }
public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { if (projectType == ProjectType.Shape && shapeSurface != null) { dstArgs.Surface.CopySurface(srcArgs.Surface, rois, startIndex, length); normalOp.Apply(dstArgs.Surface, shapeSurface, rois, startIndex, length); } else if (projectType == ProjectType.Effect && userEffect != null) { CodeLabConfigToken sect = (CodeLabConfigToken)parameters; try { userEffect.Render(sect.PreviewToken, dstArgs, srcArgs, rois, startIndex, length); } catch (Exception exc) { sect.LastExceptions.Add(exc); dstArgs.Surface.CopySurface(srcArgs.Surface); sect.UserScriptObject = null; userEffect?.Dispose(); userEffect = null; } if (fetchDebugMsg) { fetchDebugMsg = false; try { string output = userEffect?.GetType().GetProperty("__DebugMsgs", typeof(string))?.GetValue(userEffect)?.ToString(); if (!output.IsNullOrEmpty()) { sect.Output.Add(output); } } catch { // just fail silently } } } }
void Render(Surface dst, Surface src, Rectangle rect) { Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); ColorBgra currentPixel; ColorBgra fillColor = Amount3; if (Amount2) { fillColor.A = 0; } Rectangle marginBounds = Rectangle.FromLTRB(selection.Left + Amount5, selection.Top + Amount5, selection.Right - Amount5, selection.Bottom - Amount5); int radiusMax = Math.Min(selection.Width, selection.Height) / 2 - Amount5; radiusValue = (Amount1 > radiusMax) ? radiusMax : Amount1; // create a rectangle that will be used to determine how the pixels should be rendered rectangleTopCoordinate = marginBounds.Top + radiusValue; rectangleBottomCoordinate = marginBounds.Bottom - 1 - radiusValue; rectangleLeftCoordinate = marginBounds.Left + radiusValue; rectangleRightCoordinate = marginBounds.Right - 1 - radiusValue; // create point for testing how each pixel should be colored System.Windows.Point pointToTest = new System.Windows.Point(); for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { // update point's coordinates pointToTest.X = x; pointToTest.Y = y; currentPixel = src[x, y]; if (!marginBounds.Contains(x, y)) { currentPixel.A = byte.MinValue; } // if point is Not outside of the radius, use original source pixel Alpha value else if (!PointOutsideRadius(pointToTest, 0)) { // Do nothing. Alpha channel stays the same } else if (Amount4) { if (!PointOutsideRadius(pointToTest, 0.333)) { currentPixel.A = (byte)(0.7 * currentPixel.A); } else if (!PointOutsideRadius(pointToTest, 0.666)) { currentPixel.A = (byte)(0.4 * currentPixel.A); } else if (!PointOutsideRadius(pointToTest, 1)) { currentPixel.A = (byte)(0.2 * currentPixel.A); } else { currentPixel.A = byte.MinValue; } } else { currentPixel.A = byte.MinValue; } dst[x, y] = normalOp.Apply(fillColor, currentPixel); } } }
private unsafe void RenderRectangle(Surface dst, Surface src, Rectangle rect) { double shadowFactor = (double)(Token.GetProperty <Int32Property>("ShadowEffect.Alpha").Value) / 255.0; // The blurring algorithm was stolen directly from the BlurEffect code. I couldn't // use it directly because the source image must be transformed prior to applying // the blur effect. Also, I gradually increase the blur radius from one end // of the shadow to the other, which the blur effect code doesn't support either. if (rect.Height >= 1 && rect.Width >= 1) { // For each row in the rectangle for (int y = rect.Top; y < rect.Bottom; ++y) { double radius = invertedYcoordinate(y, src.Height) / (double)rowsPerBlurRadius; int[] w = CreateGaussianBlurRow(radius); int wlen = w.Length; int r = (wlen - 1) / 2; long[] waSums = new long[wlen]; long[] aSums = new long[wlen]; long waSum = 0; long aSum = 0; ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); // For each item in the gaussian blur row for (int wx = 0; wx < wlen; ++wx) { int srcX = rect.Left + wx - r; waSums[wx] = 0; aSums[wx] = 0; if (srcX >= 0 && srcX < src.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < src.Height) { ColorBgra c = getShadowPixel(srcX, srcY, src, shadowFactor, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowAngle").Value, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowDepthAngle").Value); int wp = w[wy]; waSums[wx] += wp; aSums[wx] += wp * c.A; } } int wwx = w[wx]; waSum += wwx * waSums[wx]; aSum += wwx * aSums[wx]; } } if (waSum == 0) { dstPtr->Bgra = 0; } else { dstPtr->Bgra = ColorBgra.BgraToUInt32(0, 0, 0, (int)(aSum / waSum)); } ++dstPtr; for (int x = rect.Left + 1; x < rect.Right; ++x) { ColorBgra OrginalImage = src[x, y]; for (int i = 0; i < wlen - 1; ++i) { waSums[i] = waSums[i + 1]; aSums[i] = aSums[i + 1]; } waSum = 0; aSum = 0; int wx; for (wx = 0; wx < wlen - 1; ++wx) { long wwx = (long)w[wx]; waSum += wwx * waSums[wx]; aSum += wwx * aSums[wx]; } wx = wlen - 1; waSums[wx] = 0; aSums[wx] = 0; int srcX = x + wx - r; if (srcX >= 0 && srcX < src.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < src.Height) { ColorBgra c = getShadowPixel(srcX, srcY, src, shadowFactor, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowAngle").Value, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowDepthAngle").Value); int wp = w[wy]; waSums[wx] += wp; aSums[wx] += wp * (long)c.A; } } int wr = w[wx]; waSum += (long)wr * waSums[wx]; aSum += (long)wr * aSums[wx]; } ColorBgra Shadow = new ColorBgra(); if (waSum == 0) { Shadow = ColorBgra.FromBgra(0, 0, 0, 0); } else { Shadow = ColorBgra.FromBgra(0, 0, 0, (byte)(aSum / waSum)); } if (Token.GetProperty <BooleanProperty>("ShadowEffect.OriginalImage").Value) { dstPtr->Bgra = (uint)normalOp.Apply(Shadow, OrginalImage); } else { dstPtr->Bgra = (uint)Shadow; } ++dstPtr; } } } }
/// <summary> /// Creates the shadow of the source image /// </summary> /// <param name="dst">Describes the destination surface.</param> /// <param name="src">Describes the source surface.</param> /// <param name="rect">The rectangle that describes the region of interest.</param> /// <param name="configuration"></param> /// private unsafe void RenderRectangle(Surface dst, Surface src, Rectangle rect, ShadowEffectConfiguration configuration) { double shadowFactor = configuration.Opacity / ShadowEffectProperties.MaxOpacity; // // The blurring algorithm was stolen directly from the BlurEffect code. I couldn't // use it directly because the source image must be transformed prior to applying // the blur effect. Also, I gradually increase the blur radius from one end // of the shadow to the other, which the blur effect code doesn't support either. // if (rect.Height >= 1 && rect.Width >= 1) { // For each row in the rectangle for (int y = rect.Top; y < rect.Bottom; ++y) { // // Shadow Diffusion - The blur radius increases the further the row is from the bottom // Diffusion Factor - [0-100] How much the shadow is diffused. 0 = None, 100 = Max // double blurRadius = 0; if (configuration.DiffusionFactor > 0) { // diffusion factor of 50 = 5 rows/blur_radius double rowsPerBlurRadius = 250.0 / (double)configuration.DiffusionFactor; blurRadius = invertedYcoordinate(y, src.Height) / rowsPerBlurRadius; } int[] w = CreateGaussianBlurRow(blurRadius); int wlen = w.Length; int r = (wlen - 1) / 2; long[] waSums = new long[wlen]; long[] aSums = new long[wlen]; long waSum = 0; long aSum = 0; ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); // For each item in the gaussian blur row for (int wx = 0; wx < wlen; ++wx) { int srcX = rect.Left + wx - r; waSums[wx] = 0; aSums[wx] = 0; if (srcX >= 0 && srcX < src.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < src.Height) { ColorBgra c = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle); int wp = w[wy]; waSums[wx] += wp; aSums[wx] += wp * c.A; } } int wwx = w[wx]; waSum += wwx * waSums[wx]; aSum += wwx * aSums[wx]; } } if (waSum == 0) { dstPtr->Bgra = 0; } else { dstPtr->Bgra = ColorBgra.BgraToUInt32(0, 0, 0, (int)(aSum / waSum)); } ++dstPtr; for (int x = rect.Left + 1; x < rect.Right; ++x) { ColorBgra OrginalImage = src[x, y]; for (int i = 0; i < wlen - 1; ++i) { waSums[i] = waSums[i + 1]; aSums[i] = aSums[i + 1]; } waSum = 0; aSum = 0; int wx; for (wx = 0; wx < wlen - 1; ++wx) { long wwx = (long)w[wx]; waSum += wwx * waSums[wx]; aSum += wwx * aSums[wx]; } wx = wlen - 1; waSums[wx] = 0; aSums[wx] = 0; int srcX = x + wx - r; if (srcX >= 0 && srcX < src.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < src.Height) { ColorBgra c = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle); int wp = w[wy]; waSums[wx] += wp; aSums[wx] += wp * (long)c.A; } } int wr = w[wx]; waSum += (long)wr * waSums[wx]; aSum += (long)wr * aSums[wx]; } ColorBgra Shadow = new ColorBgra(); if (waSum == 0) { Shadow = ColorBgra.FromBgra(0, 0, 0, 0); } else { Shadow = ColorBgra.FromBgra(0, 0, 0, (byte)(aSum / waSum)); } if (configuration.KeepOriginalImage) { dstPtr->Bgra = (uint)_normalOp.Apply(Shadow, OrginalImage); } else { dstPtr->Bgra = (uint)Shadow; } ++dstPtr; } } } }
void Render(Surface dst, Surface src, Rectangle rect) { Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); ColorBgra sourceColor; ColorBgra imageColor; ColorBgra fillColor = Amount3; if (Amount2) { fillColor.A = 0; } int margin = Amount5; int radiusMax = Math.Min(selection.Width, selection.Height) / 2 - margin; radiusValue = (Amount1 > radiusMax) ? radiusMax : Amount1; // create a rectangle that will be used to determine how the pixels should be rendered rectangleTopCoordinate = selection.Top + margin + radiusValue; rectangleBottomCoordinate = selection.Bottom - margin - 1 - radiusValue; rectangleLeftCoordinate = selection.Left + margin + radiusValue; rectangleRightCoordinate = selection.Right - margin - 1 - radiusValue; // create point for testing how each pixel should be colored System.Windows.Point pointToTest = new System.Windows.Point(); for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { sourceColor = src[x, y]; imageColor = sourceColor; imageColor.A = 0; // update point's coordinates pointToTest.X = x; pointToTest.Y = y; // if point is Not outside of the radius, use original source pixel Alpha value if (!PointOutsideRadius(pointToTest, 0)) { imageColor.A = sourceColor.A; } else if (Amount4) { if (!PointOutsideRadius(pointToTest, 0.333)) { imageColor.A = (byte)(0.7 * sourceColor.A); } else if (!PointOutsideRadius(pointToTest, 0.666)) { imageColor.A = (byte)(0.4 * sourceColor.A); } else if (!PointOutsideRadius(pointToTest, 1)) { imageColor.A = (byte)(0.2 * sourceColor.A); } } // Trim the margins if (margin > 0 && (x < selection.Left + margin || x > selection.Right - margin - 1 || y < selection.Top + margin || y > selection.Bottom - margin - 1)) { imageColor.A = 0; } dst[x, y] = normalOp.Apply(fillColor, imageColor); } } }