protected override PropertyCollection OnCreatePropertyCollection() { Size selection = EnvironmentParameters.GetSelection(EnvironmentParameters.SourceSurface.Bounds).GetBoundsInt().Size; int radiusMax = Math.Min(selection.Width, selection.Height) / 2; int radiusDefault = radiusMax / 2; List <Property> props = new List <Property> { new Int32Property(PropertyNames.Amount1, radiusDefault, 1, radiusMax), new BooleanProperty(PropertyNames.Amount4, true), new Int32Property(PropertyNames.Amount5, 0, 0, radiusMax), new BooleanProperty(PropertyNames.Amount2, true), new Int32Property(PropertyNames.Amount3, ColorBgra.ToOpaqueInt32(ColorBgra.FromBgra(EnvironmentParameters.PrimaryColor.B, EnvironmentParameters.PrimaryColor.G, EnvironmentParameters.PrimaryColor.R, 255)), 0, 0xffffff) }; List <PropertyCollectionRule> propRules = new List <PropertyCollectionRule> { new ReadOnlyBoundToBooleanRule(PropertyNames.Amount3, PropertyNames.Amount2, false) }; return(new PropertyCollection(props, propRules)); }
protected override ControlInfo OnCreateConfigUI(PropertyCollection props) { ControlInfo configUI = CreateDefaultConfigUI(props); configUI.SetPropertyControlValue(PropertyNames.Amount1, ControlInfoPropertyNames.DisplayName, L10nStrings.Text); configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.DisplayName, L10nStrings.TextRepeat); configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.DisplayName, L10nStrings.FontSize); configUI.SetPropertyControlValue(PropertyNames.Amount4, ControlInfoPropertyNames.DisplayName, L10nStrings.Font); PropertyControlInfo Amount4FontFamilyControl = configUI.FindControlForPropertyName(PropertyNames.Amount4); foreach (FontFamily ff in FontUtil.UsableFontFamilies) { Amount4FontFamilyControl.SetValueDisplayName(ff, ff.Name); } configUI.SetPropertyControlValue(PropertyNames.Amount5, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Amount5, ControlInfoPropertyNames.Description, L10nStrings.Bold); configUI.SetPropertyControlValue(PropertyNames.Amount6, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Amount6, ControlInfoPropertyNames.Description, L10nStrings.Italic); configUI.SetPropertyControlValue(PropertyNames.Amount7, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Amount7, ControlInfoPropertyNames.Description, L10nStrings.Underline); configUI.SetPropertyControlValue(PropertyNames.Amount8, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Amount8, ControlInfoPropertyNames.Description, L10nStrings.Strikeout); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.DisplayName, L10nStrings.Offset); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.SliderSmallChangeX, 0.05); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.SliderLargeChangeX, 0.25); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.UpDownIncrementX, 0.01); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.SliderSmallChangeY, 0.05); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.SliderLargeChangeY, 0.25); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.UpDownIncrementY, 0.01); Rectangle selection9 = EnvironmentParameters.GetSelection(EnvironmentParameters.SourceSurface.Bounds).GetBoundsInt(); ImageResource imageResource9 = ImageResource.FromImage(EnvironmentParameters.SourceSurface.CreateAliasedBitmap(selection9)); configUI.SetPropertyControlValue(PropertyNames.Amount9, ControlInfoPropertyNames.StaticImageUnderlay, imageResource9); configUI.SetPropertyControlValue(PropertyNames.Amount10, ControlInfoPropertyNames.DisplayName, L10nStrings.BackColor); configUI.SetPropertyControlType(PropertyNames.Amount10, PropertyControlType.ColorWheel); return(configUI); }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { Modes OldMode = Mode; Mode = (Modes)newToken.GetProperty <StaticListChoiceProperty>(PropertyNames.Mode).Value; ModeChanged = Mode != OldMode; LowerThreshold = newToken.GetProperty <Int32Property>(PropertyNames.LowerThreshold).Value; UpperThreshold = newToken.GetProperty <Int32Property>(PropertyNames.UpperThreshold).Value; float OldTolerance = Tolerance; Tolerance = newToken.GetProperty <Int32Property>(PropertyNames.Tolerance).Value; Tolerance *= Tolerance / toleranceMax / toleranceMax; ToleranceChanged = Tolerance != OldTolerance; base.OnSetRenderInfo(newToken, dstArgs, srcArgs); PdnRegion selection = EnvironmentParameters.GetSelection(SrcArgs.Surface.Bounds); List <RectangleRef> selRects = RectangleRef.RectanglesToRectangleRefs(selection.GetRegionScansInt()); CustomOnRender(RectangleRef.SplitSmall(selRects, selection.GetBoundsInt().Bottom / 4)); }
// Name: // Submenu: // Author: // Title: // Version: // Desc: // Keywords: // URL: // Help: void Render(Surface dst, Surface src, Rectangle rect) { // Delete any of these lines you don't need Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); int CenterX = ((selection.Right - selection.Left) / 2) + selection.Left; int CenterY = ((selection.Bottom - selection.Top) / 2) + selection.Top; ColorBgra PrimaryColor = EnvironmentParameters.PrimaryColor; ColorBgra SecondaryColor = EnvironmentParameters.SecondaryColor; int BrushWidth = (int)EnvironmentParameters.BrushWidth; ColorBgra CurrentPixel; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) { return; } for (int x = rect.Left; x < rect.Right; x++) { CurrentPixel = src[x, y]; // TODO: Add pixel processing code here // Access RGBA values this way, for example: // CurrentPixel.R = PrimaryColor.R; // CurrentPixel.G = PrimaryColor.G; // CurrentPixel.B = PrimaryColor.B; // CurrentPixel.A = PrimaryColor.A; var l = CurrentPixel.Luminance(); // if (l != CurrentPixel.GetIntensityByte()) Debug.WriteLine($"{l}/{CurrentPixel.GetIntensityByte()}"); CurrentPixel.R = l; CurrentPixel.G = l; CurrentPixel.B = l; dst[x, y] = CurrentPixel; } } }
/// <summary> /// Renders the effect over rectangular regions automatically /// determined and handled by Paint.NET for multithreading support. /// </summary> /// <param name="parameters"> /// Saved settings used to restore the GUI to the same settings it was /// saved with last time the effect was applied. /// </param> /// <param name="dstArgs">The destination canvas.</param> /// <param name="srcArgs">The source canvas.</param> /// <param name="rois"> /// A list of rectangular regions to split this effect into so it can /// be optimized by worker threads. Determined and managed by /// Paint.NET. /// </param> /// <param name="startIndex"> /// The rectangle to begin rendering with. Used in Paint.NET's effect /// multithreading process. /// </param> /// <param name="length"> /// The number of rectangles to render at once. Used in Paint.NET's /// effect multithreading process. /// </param> public override void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { //Renders the effect if the dialog is closed and accepted. if (!IsCancelRequested && !renderReady) { var src = srcArgs.Surface; var dst = dstArgs.Surface; PersistentSettings token = (PersistentSettings)dlg.EffectToken; Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Bounds).GetBoundsInt(); //Something happened, so this must be the final render. if (StaticSettings.dialogResult != StaticSettings.DialogResult.Default) { renderReady = true; } if (StaticSettings.dialogResult == StaticSettings.DialogResult.StoringImage) { if (selection.Width < 1 || selection.Height < 1) { MessageBox.Show("The size of the current selection " + "must match the size of the stored image to work."); return; } //Copies the data into the token. token.StoredImg = new Bitmap(selection.Width, selection.Height); for (int i = 0; i < selection.Width; i++) { for (int j = 0; j < selection.Height; j++) { token.StoredImg.SetPixel(i, j, src[selection.X + i, selection.Y + j]); } } } else if (StaticSettings.dialogResult == StaticSettings.DialogResult.Replacing) { if (token.StoredImg.Width != selection.Width || token.StoredImg.Height != selection.Height) { MessageBox.Show("The unedited image needs to be " + "stored, and the edited version selected " + "(with the same size)."); return; } for (int y = 0; y < src.Height; y++) { for (int x = 0; x < src.Width; x++) { Color pix = token.StoredImg.GetPixel(x, y); if (!src[x, y].Equals(ColorBgra.FromColor(pix))) { if (!token.DoInvertArea) { if (token.DoInvertPicture) { dst[x, y] = pix; } else { dst[x, y] = src[x, y]; } } else { dst[x, y] = ColorBgra.Transparent; } } else { if (!token.DoInvertArea) { dst[x, y] = ColorBgra.Transparent; } else { if (token.DoInvertPicture) { dst[x, y] = pix; } else { dst[x, y] = src[x, y]; } } } } } } } StaticSettings.dialogResult = StaticSettings.DialogResult.Default; }
protected override void OnSetRenderInfo(QuadrilateralCorrectionConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { topLeft = newToken.TopLeft; topRight = newToken.TopRight; bottomRight = newToken.BottomRight; bottomLeft = newToken.BottomLeft; autoDims = newToken.AutoDims; width = newToken.Width; height = newToken.Height; center = newToken.Center; // create filter QuadrilateralTransformation quadTrans = new QuadrilateralTransformation { SourceQuadrilateral = new List <IntPoint> { new IntPoint(topLeft.X, topLeft.Y), new IntPoint(topRight.X, topRight.Y), new IntPoint(bottomRight.X, bottomRight.Y), new IntPoint(bottomLeft.X, bottomLeft.Y) }, AutomaticSizeCalculaton = autoDims, NewWidth = width, NewHeight = height }; Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); PdnRegion exactSelection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds); Bitmap quadTransOutput; try { using (Bitmap srcImage = srcArgs.Surface.CreateAliasedBitmap(selection)) quadTransOutput = quadTrans.Apply(srcImage); } catch { quadTransOutput = new Bitmap(1, 1); } System.Drawing.Point offSet = new System.Drawing.Point { X = selection.X + (center ? (selection.Width - quadTransOutput.Width) / 2 : 0), Y = selection.Y + (center ? (selection.Height - quadTransOutput.Height) / 2 : 0) }; Bitmap alignedImage = new Bitmap(srcArgs.Surface.Width, srcArgs.Surface.Height); using (Graphics graphics = Graphics.FromImage(alignedImage)) { graphics.DrawImage(quadTransOutput, offSet); } quadTransOutput.Dispose(); if (quadrilateralSurface == null) { quadrilateralSurface = new Surface(srcArgs.Surface.Size); } quadrilateralSurface = Surface.CopyFromBitmap(alignedImage); alignedImage.Dispose(); dstArgs.Surface.Clear(exactSelection, Color.Transparent); dstArgs.Surface.CopySurface(quadrilateralSurface, exactSelection); base.OnSetRenderInfo(newToken, dstArgs, srcArgs); }
private void Run32BitFilterProxy(ref PSFilterPdnConfigToken token, IWin32Window window) { // Check that PSFilterShim exists first thing and abort if it does not. string shimPath = Path.Combine(Path.GetDirectoryName(typeof(PSFilterPdnEffect).Assembly.Location), "PSFilterShim.exe"); if (!File.Exists(shimPath)) { ShowErrorMessage(window, Resources.PSFilterShimNotFound); return; } try { using (PSFilterShimDataFolder proxyTempDir = new PSFilterShimDataFolder()) { string srcFileName = proxyTempDir.GetRandomFilePathWithExtension(".psi"); string destFileName = proxyTempDir.GetRandomFilePathWithExtension(".psi"); string parameterDataFileName = proxyTempDir.GetRandomFilePathWithExtension(".dat"); string resourceDataFileName = proxyTempDir.GetRandomFilePathWithExtension(".dat"); string descriptorRegistryFileName = proxyTempDir.GetRandomFilePathWithExtension(".dat"); string regionFileName = string.Empty; Rectangle sourceBounds = EnvironmentParameters.SourceSurface.Bounds; Rectangle selection = EnvironmentParameters.GetSelection(sourceBounds).GetBoundsInt(); if (selection != sourceBounds) { regionFileName = proxyTempDir.GetRandomFilePathWithExtension(".dat"); RegionDataWrapper selectedRegion = new RegionDataWrapper(EnvironmentParameters.GetSelection(sourceBounds).GetRegionData()); DataContractSerializerUtil.Serialize(regionFileName, selectedRegion); } bool proxyResult = true; string proxyErrorMessage = string.Empty; PSFilterShimSettings settings = new PSFilterShimSettings { RepeatEffect = true, ShowAboutDialog = false, SourceImagePath = srcFileName, DestinationImagePath = destFileName, ParentWindowHandle = window.Handle, PrimaryColor = EnvironmentParameters.PrimaryColor.ToColor(), SecondaryColor = EnvironmentParameters.SecondaryColor.ToColor(), RegionDataPath = regionFileName, ParameterDataPath = parameterDataFileName, PseudoResourcePath = resourceDataFileName, DescriptorRegistryPath = descriptorRegistryFileName, PluginUISettings = null }; using (PSFilterShimPipeServer server = new PSFilterShimPipeServer(AbortCallback, token.FilterData, settings, delegate(string data) { proxyResult = false; proxyErrorMessage = data; }, null)) { PSFilterShimImage.Save(srcFileName, EnvironmentParameters.SourceSurface, 96.0f, 96.0f); ParameterData parameterData; if (token.FilterParameters.TryGetValue(token.FilterData, out parameterData)) { DataContractSerializerUtil.Serialize(parameterDataFileName, parameterData); } if (token.PseudoResources.Count > 0) { DataContractSerializerUtil.Serialize(resourceDataFileName, token.PseudoResources); } if (token.DescriptorRegistry != null) { DataContractSerializerUtil.Serialize(descriptorRegistryFileName, token.DescriptorRegistry); } ProcessStartInfo psi = new ProcessStartInfo(shimPath, server.PipeName); using (Process proxy = Process.Start(psi)) { proxy.WaitForExit(); } } if (proxyResult && File.Exists(destFileName)) { token.Dest = PSFilterShimImage.Load(destFileName); } else if (!string.IsNullOrEmpty(proxyErrorMessage)) { ShowErrorMessage(window, proxyErrorMessage); } } } catch (ArgumentException ax) { ShowErrorMessage(window, ax.Message); } catch (IOException ex) { ShowErrorMessage(window, ex.Message); } catch (NotSupportedException ex) { ShowErrorMessage(window, ex.Message); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(window, ex.Message); } catch (Win32Exception wx) { ShowErrorMessage(window, wx.Message); } }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { base.OnSetRenderInfo(newToken, dstArgs, srcArgs); helper.IsCancelRequested = IsCancelRequested; helper.RenderText(EnvironmentParameters.GetSelection(SrcArgs.Bounds), GetSettings(newToken)); }
public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { ConfigToken token = (ConfigToken)parameters; PdnRegion selection = EnvironmentParameters.GetSelection(srcArgs.Bounds); if (changed) { changed = false; if (dialog != null) { dialog.SetProgressBarMaximum(token.effects.Count, tilesPerCpu * renderingThreadCount); dialog.EnableOKButton(false); } using (Surface scratch = new Surface(srcArgs.Size)) { scratch.CopySurface(srcArgs.Surface); for (int i = 0; i < token.effects.Count; ++i) { ScriptStep step = token.effects[i]; Type type = step.EffectType; if (type == null) { if (dialog != null) { dialog.IncrementProgressBarValue(i, 1); } } else { Effect effect = (Effect)(type.GetConstructor(Type.EmptyTypes).Invoke(new object[0])); effect.Services = Services; effect.EnvironmentParameters = new EffectEnvironmentParameters( step.PrimaryColor, step.SecondaryColor, EnvironmentParameters.BrushWidth, selection, EnvironmentParameters.SourceSurface); BackgroundEffectRenderer ber = new BackgroundEffectRenderer(effect, step.Token, dstArgs, new RenderArgs(scratch), selection, null, tilesPerCpu * renderingThreadCount, renderingThreadCount); ber.RenderedTile += (sender, e) => RenderedTile((BackgroundEffectRenderer)sender, i, e.TileCount); ber.Start(); ber.Join(); scratch.CopySurface(dstArgs.Surface); } if (IsCancelRequested) { return; } } if (dialog != null) { dialog.ClearProgressBars(); dialog.EnableOKButton(true); } } } }
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); } } }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { Amount1 = newToken.GetProperty <StringProperty>(PropertyNames.Amount1).Value; Amount2 = newToken.GetProperty <Int32Property>(PropertyNames.Amount2).Value; Amount3 = newToken.GetProperty <Int32Property>(PropertyNames.Amount3).Value; FontFamily Amount4FontFamily = (FontFamily)newToken.GetProperty <StaticListChoiceProperty>(PropertyNames.Amount4).Value; Amount4 = new FontFamily(Amount4FontFamily.Name); Amount5 = newToken.GetProperty <BooleanProperty>(PropertyNames.Amount5).Value; Amount6 = newToken.GetProperty <BooleanProperty>(PropertyNames.Amount6).Value; Amount7 = newToken.GetProperty <BooleanProperty>(PropertyNames.Amount7).Value; Amount8 = newToken.GetProperty <BooleanProperty>(PropertyNames.Amount8).Value; Amount9 = newToken.GetProperty <DoubleVectorProperty>(PropertyNames.Amount9).Value; Amount10 = ColorBgra.FromOpaqueInt32(newToken.GetProperty <Int32Property>(PropertyNames.Amount10).Value); Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); Rectangle textRect = Rectangle.Round(new RectangleF((float)Amount9.First * selection.Width + selection.Left, (float)Amount9.Second * selection.Height + selection.Top, selection.Width, selection.Height)); string text = Amount1 + " "; System.Text.StringBuilder textRepeated = new System.Text.StringBuilder(); for (int i = 0; i < Amount2; i++) { textRepeated.Append(text); } if (textSurface == null) { textSurface = new Surface(srcArgs.Surface.Size); } else { textSurface.Clear(Color.Transparent); } using (Graphics g = new RenderArgs(textSurface).Graphics) { g.TextRenderingHint = TextRenderingHint.AntiAlias; FontStyle fontStyle = FontStyle.Regular; if (Amount5) { fontStyle |= FontStyle.Bold; } if (Amount6) { fontStyle |= FontStyle.Italic; } if (Amount7) { fontStyle |= FontStyle.Underline; } if (Amount8) { fontStyle |= FontStyle.Strikeout; } TextFormatFlags flags = TextFormatFlags.Top | TextFormatFlags.WordBreak; using (Font font = new Font(Amount4, Amount3, fontStyle)) { TextRenderer.DrawText(g, textRepeated.ToString(), font, textRect, Color.Black, Color.Transparent, flags); } } base.OnSetRenderInfo(newToken, dstArgs, srcArgs); }
protected override void OnRender(Rectangle[] renderRects, int startIndex, int length) { EnvironmentParameters.GetSelection(SrcArgs.Bounds); float lightX = (float)(double)Token.GetProperty("X").Value; float lightY = (float)(double)Token.GetProperty("Y").Value; float lightZ = (float)(double)Token.GetProperty("Z").Value; Float4 num = new Float4(lightX, lightY, lightZ, 0f); for (int i = startIndex; i < (startIndex + length); i++) { Rectangle rectangle = renderRects[i]; for (int j = rectangle.Top; j < rectangle.Bottom; j++) { Float4 num3; Float4 num4; Float4 num5; Float4 num6; Float4 num7; Float4 num8; Float4 num9; Float4 num10; Float4 num11; if (j == 0) { num3 = (Float4)SrcArgs.Surface[0, j]; num4 = num3; num5 = (Float4)SrcArgs.Surface[1, j]; num6 = num3; num7 = num6; num8 = num5; num9 = (Float4)SrcArgs.Surface[0, j + 1]; num10 = num9; num11 = (Float4)SrcArgs.Surface[1, j + 1]; for (int k = rectangle.Left; k < rectangle.Right; k++) { Float4 num14 = ((Float4)((((num3 + (2f * num6)) + num9) - num5) - (2f * num8))) - num11; Float4 num15 = ((Float4)((((num3 + (2f * num4)) + num5) - num9) - (2f * num10))) - num11; float x = Float4.Dot(num14, num); float y = Float4.Dot(num15, num); Float4 num18 = new Float4(x, y, 1f, 0f); num18.Normalize(); num18 = (Float4)((num18 * 0.5f) + 0.5f); num18.W = 1f; DstArgs.Surface[k, j] = (ColorBgra)num18; if (k == (rectangle.Right - 1)) { break; } num3 = num4; num4 = num5; num5 = (Float4)SrcArgs.Surface[k + 1, j]; num6 = num7; num7 = num8; num8 = num5; num9 = num10; num10 = num11; num11 = (Float4)SrcArgs.Surface[k + 1, j + 1]; } } else if (j == (rectangle.Bottom - 1)) { num3 = (Float4)SrcArgs.Surface[0, j - 1]; num4 = num3; num5 = (Float4)SrcArgs.Surface[1, j - 1]; num6 = (Float4)SrcArgs.Surface[0, j]; num7 = num6; num8 = (Float4)SrcArgs.Surface[1, j]; num9 = num6; num10 = num9; num11 = num8; for (int m = rectangle.Left; m < rectangle.Right; m++) { Float4 num20 = ((Float4)((((num3 + (2f * num6)) + num9) - num5) - (2f * num8))) - num11; Float4 num21 = ((Float4)((((num3 + (2f * num4)) + num5) - num9) - (2f * num10))) - num11; float num22 = Float4.Dot(num20, num); float num23 = Float4.Dot(num21, num); Float4 num24 = new Float4(num22, num23, 1f, 0f); num24.Normalize(); num24 = (Float4)((num24 * 0.5f) + 0.5f); num24.W = 1f; DstArgs.Surface[m, j] = (ColorBgra)num24; if (m == (rectangle.Right - 1)) { break; } num3 = num4; num4 = num5; num5 = (Float4)SrcArgs.Surface[m + 1, j - 1]; num6 = num7; num7 = num8; num8 = (Float4)SrcArgs.Surface[m + 1, j]; num9 = num10; num10 = num11; num11 = num8; } } else { num3 = (Float4)SrcArgs.Surface[0, j - 1]; num4 = num3; num5 = (Float4)SrcArgs.Surface[1, j - 1]; num6 = (Float4)SrcArgs.Surface[0, j]; num7 = num6; num8 = (Float4)SrcArgs.Surface[1, j]; num9 = (Float4)SrcArgs.Surface[0, j + 1]; num10 = num9; num11 = (Float4)SrcArgs.Surface[1, j + 1]; for (int n = rectangle.Left; n < rectangle.Right; n++) { Float4 num26 = ((Float4)((((num3 + (2f * num6)) + num9) - num5) - (2f * num8))) - num11; Float4 num27 = ((Float4)((((num3 + (2f * num4)) + num5) - num9) - (2f * num10))) - num11; float num28 = Float4.Dot(num26, num); float num29 = Float4.Dot(num27, num); Float4 num30 = new Float4(num28, num29, 1f, 0f); num30.Normalize(); num30 = (Float4)((num30 * 0.5f) + 0.5f); num30.W = 1f; DstArgs.Surface[n, j] = (ColorBgra)num30; if (n == (rectangle.Right - 1)) { break; } num3 = num4; num4 = num5; num5 = (Float4)SrcArgs.Surface[n + 1, j - 1]; num6 = num7; num7 = num8; num8 = (Float4)SrcArgs.Surface[n + 1, j]; num9 = num10; num10 = num11; num11 = (Float4)SrcArgs.Surface[n + 1, j + 1]; } } } } }
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); } } }
/// <summary> /// Renders the effect over rectangular regions automatically /// determined and handled by Paint.NET for multithreading support. /// </summary> /// <param name="parameters"> /// Saved settings used to restore the GUI to the same settings it was /// saved with last time the effect was applied. /// </param> /// <param name="dstArgs">The destination canvas.</param> /// <param name="srcArgs">The source canvas.</param> /// <param name="rois"> /// A list of rectangular regions to split this effect into so it can /// be optimized by worker threads. Determined and managed by /// Paint.NET. /// </param> /// <param name="startIndex"> /// The rectangle to begin rendering with. Used in Paint.NET's effect /// multithreading process. /// </param> /// <param name="length"> /// The number of rectangles to render at once. Used in Paint.NET's /// effect multithreading process. /// </param> public override void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { //Renders the effect if the dialog is closed and accepted. if (!IsCancelRequested && !renderReady) { var src = srcArgs.Surface; var dst = dstArgs.Surface; PersistentSettings token = (PersistentSettings)dlg.EffectToken; Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Bounds).GetBoundsInt(); //Something happened, so this must be the final render. if (StaticSettings.dialogResult != StaticSettings.DialogResult.Default) { renderReady = true; } if (StaticSettings.dialogResult == StaticSettings.DialogResult.StoringFirstImage) { if (selection.Width <= 1 || selection.Height <= 1 || ((token.BmpReplacing.Width != selection.Width || token.BmpReplacing.Height != selection.Height) && (token.BmpReplacing.Width != 1 && token.BmpReplacing.Height != 1))) { MessageBox.Show("The image to replace and its " + "replacing image must be the same size, and " + "the selection must be larger than a pixel."); return; } //Copies the data into the token. token.BmpToReplace = new Bitmap(selection.Width, selection.Height); for (int i = 0; i < selection.Width; i++) { for (int j = 0; j < selection.Height; j++) { token.BmpToReplace.SetPixel(i, j, src[selection.X + i, selection.Y + j]); } } } else if (StaticSettings.dialogResult == StaticSettings.DialogResult.StoringSecondImage) { if (selection.Width <= 1 || selection.Height <= 1 || ((token.BmpToReplace.Width != selection.Width || token.BmpToReplace.Height != selection.Height) && (token.BmpToReplace.Width != 1 && token.BmpToReplace.Height != 1))) { MessageBox.Show("The image to replace and its " + "replacing image must be the same size, and " + "the selection must be larger than a pixel."); return; } //Copies the data into the token. token.BmpReplacing = new Bitmap(selection.Width, selection.Height); for (int i = 0; i < selection.Width; i++) { for (int j = 0; j < selection.Height; j++) { token.BmpReplacing.SetPixel(i, j, src[selection.X + i, selection.Y + j]); } } } else if (StaticSettings.dialogResult == StaticSettings.DialogResult.Replacing) { if (token.BmpToReplace.Width != token.BmpReplacing.Width || token.BmpToReplace.Height != token.BmpReplacing.Height || token.BmpToReplace.Width == 1 || token.BmpToReplace.Height == 1) { MessageBox.Show("Both images must be selected first."); return; } List <Point> replacedPixels = new List <Point>(); //Looks at each pixel and compares it to the top-left //corner of the first image. Skips pixels that are too //far to the right or bottom to contain the entire image. //Tracks the pixel location. When a match is found, all //its pixels are checked. If everything matches, those //pixels are replaced immediately and added to a list of //pixels to skip over. dst.CopySurface(src); for (int y = 0; y <= src.Height - token.BmpToReplace.Height; y++) { for (int x = 0; x <= src.Width - token.BmpToReplace.Width; x++) { //Skips all pixels that have been replaced. if (replacedPixels.Count > 0 && replacedPixels[0].X == x && replacedPixels[0].Y == y) { replacedPixels.RemoveAt(0); continue; } //Checks if the first pixel matches. if (ColorsMatch(ColorBgra.FromColor( token.BmpToReplace.GetPixel(0, 0)), src[x, y], token.Tolerance)) { bool totalMatch = true; //Checks if every pixel matches. for (int yy = 0; yy < token.BmpToReplace.Height; yy++) { for (int xx = 0; xx < token.BmpToReplace.Width; xx++) { if (!ColorsMatch(ColorBgra.FromColor( token.BmpToReplace.GetPixel(xx, yy)), src[x + xx, y + yy], token.Tolerance)) { totalMatch = false; break; } } if (!totalMatch) { break; } } //Replaces the matching pixels. They will be skipped. if (totalMatch) { for (int yy = 0; yy < token.BmpReplacing.Height; yy++) { for (int xx = 0; xx < token.BmpReplacing.Width; xx++) { dst[x + xx, y + yy] = ColorBgra.FromColor(token.BmpReplacing.GetPixel(xx, yy)); //All pixels except the first should be skipped. //The first has been checked already. if (xx != 0 && yy != 0) { replacedPixels.Add(new Point(x + xx, y + yy)); } } } replacedPixels.OrderBy(p => p.X).ThenBy(p => p.Y); } } } } } } StaticSettings.dialogResult = StaticSettings.DialogResult.Default; }
//public override EffectConfigDialog CreateConfigDialog() //{ // return new EffectPluginConfigDialog(); //} public void RenderRI(RenderArgs dstArgs, RenderArgs srcArgs, Rectangle rois) { //EffectPluginConfigToken effectPluginConfigToken = (EffectPluginConfigToken)parameters; //int size = effectPluginConfigToken.ApertureSize; int size = Value2; PdnRegion selectionRegion = EnvironmentParameters.GetSelection(srcArgs.Bounds); // Delete any of these lines you don't need Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Bounds).GetBoundsInt(); int CenterX = ((selection.Right - selection.Left) / 2) + selection.Left; int CenterY = ((selection.Bottom - selection.Top) / 2) + selection.Top; ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor; ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor; int BrushWidth = (int)EnvironmentParameters.BrushWidth; Random TempRandom = new Random(); int[] ApetureMinX = { -(size / 2), 0, -(size / 2), 0 }; int[] ApetureMaxX = { 0, (size / 2), 0, (size / 2) }; int[] ApetureMinY = { -(size / 2), -(size / 2), 0, 0 }; int[] ApetureMaxY = { 0, 0, (size / 2), (size / 2) }; //ColorBgra CurrentPixel; //for (int w = startIndex; w < startIndex + length; ++w) //{ /* Java source from original*/ Rectangle roi = rois; //[w]; int width = roi.Width; int height = roi.Height; int size2 = (size + 1) / 2; int offset = (size - 1) / 2; int width2 = srcArgs.Width + offset; int height2 = srcArgs.Height + offset; ValueSurface means = new ValueSurface { Width = width2, Height = height2 }; //double[,] meanr = new double[width2, height2]; double[,] variancer = new double[width2, height2]; //double[,] meang = new double[width2, height2]; double[,] varianceg = new double[width2, height2]; //double[,] meanb = new double[width2, height2]; double[,] varianceb = new double[width2, height2]; int x1Start = roi.X; int y1Start = roi.Y; for (int y1 = y1Start - offset; y1 < y1Start + height; y1++) { //if ((y1%20)==0) IJ.showProgress(0.7*(y1-y1start)/height); for (int x1 = x1Start - offset; x1 < x1Start + width; x1++) { double sumr = 0; double sumr2 = 0; double sumg = 0; double sumg2 = 0; double sumb = 0; double sumb2 = 0; int n = 0; for (int x2 = x1; x2 < x1 + size2; x2++) { if (x2 < 0 || x2 >= srcArgs.Bounds.Right) { continue; } for (int y2 = y1; y2 < y1 + size2; y2++) { if (y2 < 0 || y2 >= srcArgs.Bounds.Bottom) { continue; } int vr = srcArgs.Surface[x2, y2].R; sumr += vr; sumr2 += vr * vr; int vg = srcArgs.Surface[x2, y2].G; sumg += vg; sumg2 += vg * vg; int vb = srcArgs.Surface[x2, y2].B; sumb += vb; sumb2 += vb * vb; n++; } } means[x1 + offset, y1 + offset].kolor = new Kolor(sumr / n, sumg / n, sumb / n); //meanr[x1 + offset, y1 + offset] = sumr / n; variancer[x1 + offset, y1 + offset] = sumr2 - sumr * sumr / n; //meang[x1 + offset, y1 + offset] = sumg / n; varianceg[x1 + offset, y1 + offset] = sumg2 - sumg * sumg / n; //meanb[x1 + offset, y1 + offset] = sumb / n; varianceb[x1 + offset, y1 + offset] = sumb2 - sumb * sumb / n; } } //new ImagePlus("Variance", new FloatProcessor(variance)).show(); // ImageJ 1.35b or later int xbase2 = 0; int ybase2 = 0; for (int y1 = y1Start; y1 < y1Start + height; y1++) { //if ((y1%20)==0) IJ.showProgress(0.7+0.3*(y1-y1start)/height); for (int x1 = x1Start; x1 < x1Start + width; x1++) { double minr = double.MaxValue; double ming = double.MaxValue; double minb = double.MaxValue; int xbase = x1; //double xbase; int ybase = y1; //double ybase; double varr = variancer[xbase, ybase]; double varg = varianceg[xbase, ybase]; double varb = varianceb[xbase, ybase]; if (varr < minr) { minr = varr; xbase2 = xbase; ybase2 = ybase; } if (varg < ming) { ming = varg; xbase2 = xbase; ybase2 = ybase; } if (varb < minb) { minb = varb; xbase2 = xbase; ybase2 = ybase; } xbase = x1 + offset; varr = variancer[xbase, ybase]; varg = varianceg[xbase, ybase]; varb = varianceb[xbase, ybase]; if (varr < minr) { minr = varr; xbase2 = xbase; ybase2 = ybase; } if (varg < ming) { ming = varg; xbase2 = xbase; ybase2 = ybase; } if (varb < minb) { minb = varb; xbase2 = xbase; ybase2 = ybase; } ybase = y1 + offset; varr = variancer[xbase, ybase]; varg = varianceg[xbase, ybase]; varb = varianceb[xbase, ybase]; if (varr < minr) { minr = varr; xbase2 = xbase; ybase2 = ybase; } if (varg < ming) { ming = varg; xbase2 = xbase; ybase2 = ybase; } if (varb < minb) { minb = varb; xbase2 = xbase; ybase2 = ybase; } xbase = x1; varr = variancer[xbase, ybase]; varg = varianceg[xbase, ybase]; varb = varianceb[xbase, ybase]; if (varr < minr) { minr = varr; xbase2 = xbase; ybase2 = ybase; } if (varg < ming) { ming = varg; xbase2 = xbase; ybase2 = ybase; } if (varb < minb) { minb = varb; xbase2 = xbase; ybase2 = ybase; } ColorBgra tempColorBgra = new ColorBgra(); tempColorBgra = (byte)(means[xbase2, ybase2] + 0.5); //tempColorBgra.R = (byte)(meanr[xbase2, ybase2] + 0.5); tempColorBgra.G = (byte)(meang[xbase2, ybase2] + 0.5); tempColorBgra.B = (byte)(meanb[xbase2, ybase2] + 0.5); tempColorBgra.A = (byte)255; dstArgs.Surface[x1, y1] = tempColorBgra; } } //IJ.showProgress(1.0); /* End of Java source */ // Rectangle rect = rois[w]; // for (int y = rect.Top; y < rect.Bottom; ++y) // { // for (int x = rect.Left; x < rect.Right; ++x) // { // //OutputDebugStringW("ApetureMinX[]: " + ApetureMinX[0] + "," +ApetureMinX[1] + "," +ApetureMinX[2] + "," +ApetureMinX[3]); // //OutputDebugStringW("ApetureMaxX[]: " + ApetureMaxX[0] + "," + ApetureMaxX[1] + "," + ApetureMaxX[2] + "," + ApetureMaxX[3]); // //OutputDebugStringW("ApetureMinY[]: " + ApetureMinY[0] + "," + ApetureMinY[1] + "," + ApetureMinY[2] + "," + ApetureMinY[3]); // //OutputDebugStringW("ApetureMinX[]: " + ApetureMaxY[0] + "," + ApetureMaxY[1] + "," + ApetureMaxY[2] + "," + ApetureMaxY[3]); // //for (int y = selection.Top; y < selection.Bottom; y++) // //{ // // //OutputDebugStringW("Y position: " + y); // // for (int x = selection.Left; x < selection.Right; x++) // // { // CurrentPixel = srcArgs.Surface[x, y]; // ColorBgra NewPixel = new ColorBgra(); //dstArgs.Surface[x, y]; // int[] RValues = { 0, 0, 0, 0 }; // int[] GValues = { 0, 0, 0, 0 }; // int[] BValues = { 0, 0, 0, 0 }; // int[] NumPixels = { 0, 0, 0, 0 }; // int[] MaxRValue = { 0, 0, 0, 0 }; // int[] MaxGValue = { 0, 0, 0, 0 }; // int[] MaxBValue = { 0, 0, 0, 0 }; // int[] MinRValue = { 255, 255, 255, 255 }; // int[] MinGValue = { 255, 255, 255, 255 }; // int[] MinBValue = { 255, 255, 255, 255 }; // for (int i = 0; i < 4; ++i) // { // for (int x2 = ApetureMinX[i]; x2 < ApetureMaxX[i]; ++x2) // { // //if (y == selection.Top && x == selection.Left) // //{ // // OutputDebugStringW("x2: " + x2 + ", x: " + x + ", i: " + i + ", ApetureMinX[i]: " + ApetureMinX[i] + ", ApetureMaxX[i]: " + ApetureMaxX[i]); // //} // int TempX = x + x2; // // MessageBox.Show( // //"y = " + y.ToString() + "; " + // //"x = " + x.ToString() + "; " + // //"i = " + i.ToString() + "; " + // //"x2 = " + x2.ToString() + "; " + // //"ApetureMinX[i] = " + ApetureMinX[i].ToString() + "; " + // //"ApetureMaxX[i] = " + ApetureMaxX[i].ToString() + "; " + // // "TempX = " + TempX.ToString() + "; " + // // "selection.Width = " + selection.Width.ToString() + "; " // // ); // if (TempX >= 0 && TempX < selection.Left + selection.Width) // { // for (int y2 = ApetureMinY[i]; y2 < ApetureMaxY[i]; ++y2) // { // int TempY = y + y2; // //OutputDebugStringW("TempY = " + TempY.ToString() + "; " + // // "selection.Height = " + selection.Height.ToString() + "; " // // ); // if (TempY >= 0 && TempY < selection.Bottom + selection.Height) // { // //Color TempColor = src.GetPixel(TempX, TempY); // //MessageBox.Show( // // "R = " + CurrentPixel.R.ToString() + "; " + // // "G = " + CurrentPixel.G.ToString() + "; " + // // "B = " + CurrentPixel.B.ToString() + "; " + // //"MaxRValue[i] = " + MaxRValue[i].ToString() + "; " + // //"MinRValue[i] = " + MinRValue[i].ToString() + "; " + // //"MaxGValue[i] = " + MaxGValue[i].ToString() + "; " + // //"MinGValue[i] = " + MinGValue[i].ToString() + "; " + // //"MaxBValue[i] = " + MaxBValue[i].ToString() + "; " + // //"MinBValue[i] = " + MinBValue[i].ToString() + "; " // // ); // //Color TempColor = TempBitmap.GetPixel(TempX, TempY); // NewPixel = srcArgs.Surface[x, y]; // RValues[i] += NewPixel.R; //TempColor.R; // GValues[i] += NewPixel.G; //TempColor.G; // BValues[i] += NewPixel.B; //TempColor.B; // if (NewPixel.R > MaxRValue[i]) // { // MaxRValue[i] = NewPixel.R; // } // else if (NewPixel.R < MinRValue[i]) // { // MinRValue[i] = NewPixel.R; // } // if (NewPixel.G > MaxGValue[i]) // { // MaxGValue[i] = NewPixel.G; // } // else if (NewPixel.G < MinGValue[i]) // { // MinGValue[i] = NewPixel.G; // } // if (NewPixel.B > MaxBValue[i]) // { // MaxBValue[i] = NewPixel.B; // } // else if (NewPixel.B < MinBValue[i]) // { // MinBValue[i] = NewPixel.B; // } // ++NumPixels[i]; // } // } // } // } // } // int j = 0; // int MinDifference = 10000; // for (int i = 0; i < 4; ++i) // { // int CurrentDifference = (MaxRValue[i] - MinRValue[i]) + (MaxGValue[i] - MinGValue[i]) + (MaxBValue[i] - MinBValue[i]); // if (CurrentDifference < MinDifference && NumPixels[i] > 0) // { // j = i; // MinDifference = CurrentDifference; // } // } // //MessageBox.Show( // // "NumPixels[j] = " + NumPixels[j].ToString() + "; " + // // "RValues[j] = " + RValues[j].ToString() + "; " + // // "GValues[j] = " + GValues[j].ToString() + "; " + // //"BValues[j] = " + BValues[j].ToString() + "; " + // //"(byte)255 = " + (byte)255 + "; " // // ); // ColorBgra MeanPixel = new ColorBgra(); // MeanPixel.R = NumPixels[j] == 0 ? (byte)RValues[j] : (byte)(RValues[j] / NumPixels[j]); // MeanPixel.G = NumPixels[j] == 0 ? (byte)GValues[j] : (byte)(GValues[j] / NumPixels[j]); // MeanPixel.B = NumPixels[j] == 0 ? (byte)BValues[j] : (byte)(BValues[j] / NumPixels[j]); // MeanPixel.A = (byte)255; // //NewBitmap.SetPixel(x, y, MeanPixel); // // TODO: Add pixel processing code here // // Access RGBA values this way, for example: // // CurrentPixel.R = (byte)PrimaryColor.R; // // CurrentPixel.G = (byte)PrimaryColor.G; // // CurrentPixel.B = (byte)PrimaryColor.B; // // CurrentPixel.A = (byte)PrimaryColor.A; // dstArgs.Surface[x, y] = MeanPixel; // // } // //} // } // } //} }