private DialogResult ProcessOutputImages() { DialogResult result = DialogResult.Cancel; OutputImageState state = server.OutputImageState; if (state.Error != null) { ShowErrorMessage(state.Error); } else { IReadOnlyList <Surface> outputImages = state.OutputImages; string gmicCommandName = server.GmicCommandName; if (outputImages.Count > 1) { if (!string.IsNullOrWhiteSpace(outputFolder)) { folderBrowserDialog.SelectedPath = outputFolder; } if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK) { outputFolder = folderBrowserDialog.SelectedPath; try { OutputImageUtil.SaveAllToFolder(outputImages, outputFolder, gmicCommandName); surface?.Dispose(); surface = null; result = DialogResult.OK; } catch (ArgumentException ex) { ShowErrorMessage(ex); } catch (ExternalException ex) { ShowErrorMessage(ex); } catch (IOException ex) { ShowErrorMessage(ex); } catch (SecurityException ex) { ShowErrorMessage(ex); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(ex); } } } else { Surface output = outputImages[0]; if (output.Size == EnvironmentParameters.SourceSurface.Size) { if (surface == null) { surface = new Surface(EnvironmentParameters.SourceSurface.Width, EnvironmentParameters.SourceSurface.Height); } surface.CopySurface(output); result = DialogResult.OK; } else { if (surface != null) { surface.Dispose(); surface = null; } // Place the full image on the clipboard when the size does not match the Paint.NET layer // and prompt the user to save it. // The resized image will not be copied to the Paint.NET canvas. Services.GetService <IClipboardService>().SetImage(output); resizedImageSaveDialog.FileName = gmicCommandName + "_" + DateTime.Now.ToString("yyyyMMdd-THHmmss") + ".png"; if (resizedImageSaveDialog.ShowDialog(this) == DialogResult.OK) { string resizedImagePath = resizedImageSaveDialog.FileName; try { using (Bitmap bitmap = output.CreateAliasedBitmap()) { bitmap.Save(resizedImagePath, System.Drawing.Imaging.ImageFormat.Png); } result = DialogResult.OK; } catch (ArgumentException ex) { ShowErrorMessage(ex); } catch (ExternalException ex) { ShowErrorMessage(ex); } catch (IOException ex) { ShowErrorMessage(ex); } catch (SecurityException ex) { ShowErrorMessage(ex); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(ex); } } } } FinishTokenUpdate(); } return(result); }
protected override void OnSetRenderInfo(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs) { if (repeatEffect) { GmicConfigToken token = (GmicConfigToken)parameters; if (token.Surface != null) { token.Surface.Dispose(); token.Surface = null; } if (File.Exists(GmicConfigDialog.GmicPath)) { try { using (GmicPipeServer server = new()) { List <GmicLayer> layers = new(); Surface clipboardSurface = null; try { // Some G'MIC filters require the image to have more than one layer. // Because use Paint.NET does not currently support Effect plug-ins accessing // other layers in the document, allowing the user to place the second layer on // the clipboard is supported as a workaround. clipboardSurface = Services.GetService <IClipboardService>().TryGetSurface(); if (clipboardSurface != null) { layers.Add(new GmicLayer(clipboardSurface, true)); clipboardSurface = null; } } finally { if (clipboardSurface != null) { clipboardSurface.Dispose(); } } layers.Add(new GmicLayer(EnvironmentParameters.SourceSurface, false)); server.AddLayers(layers); server.Start(); string arguments = string.Format(CultureInfo.InvariantCulture, ".PDN {0} reapply", server.FullPipeName); using (Process process = new()) { process.StartInfo = new ProcessStartInfo(GmicConfigDialog.GmicPath, arguments); process.Start(); process.WaitForExit(); if (process.ExitCode == GmicExitCode.Ok) { OutputImageState state = server.OutputImageState; if (state.Error != null) { ShowErrorMessage(state.Error); } else { IReadOnlyList <Surface> outputImages = state.OutputImages; string gmicCommandName = server.GmicCommandName; if (outputImages.Count > 1) { using (PlatformFolderBrowserDialog folderBrowserDialog = new()) { folderBrowserDialog.ClassicFolderBrowserDescription = Resources.ClassicFolderBrowserDescription; folderBrowserDialog.VistaFolderBrowserTitle = Resources.VistaFolderBrowserTitle; if (!string.IsNullOrWhiteSpace(token.OutputFolder)) { folderBrowserDialog.SelectedPath = token.OutputFolder; } if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { string outputFolder = folderBrowserDialog.SelectedPath; try { OutputImageUtil.SaveAllToFolder(outputImages, outputFolder, gmicCommandName); } catch (ArgumentException ex) { ShowErrorMessage(ex); } catch (ExternalException ex) { ShowErrorMessage(ex); } catch (IOException ex) { ShowErrorMessage(ex); } catch (SecurityException ex) { ShowErrorMessage(ex); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(ex); } } } } else { Surface output = outputImages[0]; if (output.Width == srcArgs.Surface.Width && output.Height == srcArgs.Surface.Height) { token.Surface = output.Clone(); } else { // Place the full image on the clipboard when the size does not match the Paint.NET layer // and prompt the user to save it. // The resized image will not be copied to the Paint.NET canvas. Services.GetService <IClipboardService>().SetImage(output); using (PlatformFileSaveDialog resizedImageSaveDialog = new()) { resizedImageSaveDialog.Filter = Resources.ResizedImageSaveDialogFilter; resizedImageSaveDialog.Title = Resources.ResizedImageSaveDialogTitle; resizedImageSaveDialog.FileName = gmicCommandName + "_" + DateTime.Now.ToString("yyyyMMdd-THHmmss") + ".png"; if (resizedImageSaveDialog.ShowDialog() == DialogResult.OK) { string resizedImagePath = resizedImageSaveDialog.FileName; try { using (Bitmap bitmap = output.CreateAliasedBitmap()) { bitmap.Save(resizedImagePath, System.Drawing.Imaging.ImageFormat.Png); } } catch (ArgumentException ex) { ShowErrorMessage(ex); } catch (ExternalException ex) { ShowErrorMessage(ex); } catch (IOException ex) { ShowErrorMessage(ex); } catch (SecurityException ex) { ShowErrorMessage(ex); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(ex); } } } } } } } else { switch (process.ExitCode) { case GmicExitCode.ImageTooLargeForX86: ShowErrorMessage(Resources.ImageTooLargeForX86); break; } } } } } catch (ArgumentException ex) { ShowErrorMessage(ex); } catch (ExternalException ex) { ShowErrorMessage(ex); } catch (IOException ex) { ShowErrorMessage(ex); } catch (UnauthorizedAccessException ex) { ShowErrorMessage(ex); } } else { ShowErrorMessage(Resources.GmicNotFound); } } base.OnSetRenderInfo(parameters, dstArgs, srcArgs); }