public static async Task ProcessImage( [QueueInput("uploads")] Message message, [BlobInput("uploads/{BlobName}")] Stream input, [BlobOutput("memes/{BlobName}")] Stream output) { var encoder = new AnimatedGifEncoder(); encoder.SetRepeat(0); int delay; var frames = ProcessInputFrames(input, message.OverlayText.ToUpperInvariant(), out delay); encoder.SetDelay(delay); using (var result = new MemoryStream()) { encoder.Start(result); var idx = 1; foreach (var frame in frames) { Console.WriteLine("Adding frame #{0}/{1}", idx, frames.Count); encoder.AddFrame(frame); idx++; } encoder.Finish(); result.Position = 0; result.CopyTo(output); } var uri = SetMetadataAndCleanup(message); await SendCompleteNotification(message, uri); }
private void SaveAsAnimatedGif() { //if (this.saveFileDialog.ShowDialog() == DialogResult.OK) //{ // AnimatedGifWriter writer = new AnimatedGifWriter(this.saveFileDialog.FileName); // writer.Frames = this.images; // writer.Save(); //} AnimatedGifEncoder animation = new AnimatedGifEncoder(); if (this.saveFileDialog.ShowDialog() == DialogResult.OK) { animation.Start(this.saveFileDialog.FileName); } animation.Delay = 200; animation.Quality = 1; //-1:no repeat,0:always repeat animation.RepeatTimes = 0; foreach (Image frame in this.images) { animation.AddFrame(frame); } animation.Finish(); }
public void ResizeToThumbnailTest() { string filename = Path.GetTempFileName(); Console.WriteLine("Creating: {0}", filename); try { MemoryStream ms = new MemoryStream(); AnimatedGifEncoder encoder = new AnimatedGifEncoder(); encoder.SetFrameRate(5); encoder.Start(ms); for (char i = 'a'; i <= 'e'; i++) { Console.Write(i.ToString()); encoder.AddFrame(ThumbnailBitmap.GetBitmapFromText( i.ToString(), 48, 300, 200)); } Console.WriteLine(); encoder.Finish(); ms.Flush(); ms.Seek(0, SeekOrigin.Begin); ThumbnailBitmap bitmap = new ThumbnailBitmap(ms); FileStream fs = File.Create(filename); byte[] th = bitmap.Thumbnail; fs.Write(th, 0, th.Length); fs.Close(); } finally { if (File.Exists(filename)) { File.Delete(filename); } } }
private void button11_Click(object sender, EventArgs e) { string FileName1 = "D:\\环形水波纹效果"; string ImageFormat = ".PNG"; int number = int.Parse(textBox4.Text); String[] imageFilePaths = new string[number]; for (int i = 0; i <= number - 1; i++) { imageFilePaths[i] = FileName1 + "\\" + i.ToString() + ImageFormat; } String outputFilePath = "d:\\test.gif"; AnimatedGifEncoder e1 = new AnimatedGifEncoder(); e1.Start(outputFilePath); e1.SetDelay(50); // 延迟间隔 e1.SetRepeat(0); //-1:不循环,0:总是循环 播放 for (int j = 0; j <= number - 1; j++) { e1.AddFrame(Image.FromFile(imageFilePaths[j])); } e1.Finish(); }
/// <summary> /// 生产动画图片(必须相同格式图片) /// </summary> /// <param name="imagePaths">输入源图片路径</param> /// <param name="outputPath">输出动画路径</param> /// <param name="delay">时间间隔(毫秒)</param> /// <param name="loop">重复 </param> /// <param name="w">宽度默认0 不设置</param> /// <param name="h">高度默认0 不设置</param> /// <returns>是否成功</returns> public bool GetGifImage(string[] imagePaths, string outputPath, int delay = 500, bool loop = true, int w = 0, int h = 0) { try { foreach (var imgFilePath in imagePaths) { if (!File.Exists(imgFilePath)) { return(false); } } if (File.Exists(outputPath)) { File.Delete(outputPath); } AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder(); animatedGifEncoder.Start(outputPath); animatedGifEncoder.SetDelay(delay); // 延迟间隔 animatedGifEncoder.SetRepeat(loop ? 0 : -1); //-1:不循环,0:总是循环 播放 if (w != 0 || h != 0) { animatedGifEncoder.SetSize(w, h); } foreach (var sImage in imagePaths) { animatedGifEncoder.AddFrame(Image.FromFile(sImage)); } animatedGifEncoder.Finish(); return(File.Exists(outputPath)); } catch (Exception ex) { return(false); } }
public void ConsumeAnimatedGIFTest() { MemoryStream ms = new MemoryStream(); AnimatedGifEncoder encoder = new AnimatedGifEncoder(); // encoder.SetDelay(200); encoder.SetFrameRate(5); encoder.Start(ms); for (char i = 'a'; i <= 'z'; i++) { Console.Write(i.ToString()); encoder.AddFrame(ThumbnailBitmap.GetBitmapFromText(i.ToString(), 48, 100, 200)); } Console.WriteLine(); encoder.Finish(); ms.Flush(); ms.Seek(0, SeekOrigin.Begin); GifDecoder decoder = new GifDecoder(); decoder.Read(ms); Console.WriteLine("Frames: {0}", decoder.GetFrameCount()); Assert.AreEqual(26, decoder.GetFrameCount()); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e22"></param> private void button1_Click(object sender, EventArgs e22) { int width = 200; //寬度 int heigt = 200; //高度 bool bool_修改size = checkBox_size.Checked; //如果需要修改size的話 if (bool_修改size) { try { width = Int32.Parse(textBox_w.Text.Trim()); //寬度 heigt = Int32.Parse(textBox_h.Text.Trim());; //高度 } catch { MessageBox.Show("Image size error", "Error"); return; } } if (width < 1 || heigt < 1) { MessageBox.Show("Image size error", "Error"); return; } DateTime time_start = DateTime.Now;//計時開始 取得目前時間 label_進度.Text = "0%"; button_執行.Visible = false;//隱藏執行按鈕 //this.Enabled = false; string outputFilePath = textBox_output_path.Text; //如果檔案已經存在,就先刪除。否則會有BUG if (File.Exists(outputFilePath)) { File.Delete(outputFilePath); } new Thread(() => { AnimatedGifEncoder gif = new AnimatedGifEncoder(); gif.Start(outputFilePath); gif.SetRepeat(0); //1表示只动一次,0:表示循环,n:表示循环n次 for (int i = 0; i < ar_img.Count; i++) { //程式被結束前,結束迴圈 if (bool_程式執行中 == false) { gif.Finish(); return; } //必當檔案不存在 if (File.Exists(ar_img[i].path) == false) { MessageBox.Show("找不到檔案:\n" + ar_img[i].path, "Erroe"); break; } //修改進度 this.Invoke(new MethodInvoker(() => {//委託UI行緒 if (bool_程式執行中) { label_進度.Text = ((100 * 1.0f / ar_img.Count) * (i + 1)).ToString("0.0") + "%"; } })); //設定延遲 gif.SetDelay(ar_img[i].delay); if (bool_修改size) //強制修改大小 { using (var img = Image.FromFile(ar_img[i].path)) { //ImageFormat format = img.RawFormat; using (Bitmap imgoutput = new Bitmap(img, width, heigt)) { //輸出一個新圖片 gif.AddFrame(imgoutput); } } } else //預設大小 { using (var img = Image.FromFile(ar_img[i].path)) { gif.AddFrame(img); img.Dispose(); } } }//for gif.Finish(); this.Invoke(new MethodInvoker(() => { //委託UI行緒 DateTime time_end = DateTime.Now; //計時結束 取得目前時間 String result2 = ((TimeSpan)(time_end - time_start)).TotalMilliseconds.ToString("0.0"); //後面的時間減前面的時間後 轉型成TimeSpan即可印出時間差 button_執行.Visible = true; //this.Enabled = true; MessageBox.Show("運行時間:" + result2 + " 毫秒\n" + "檔案大小:" + fun_判斷檔案大小(outputFilePath), "輸出完成"); })); }).Start(); // textBox1.Text=( result2 + " 毫秒"); }
public void Execute(object data) { try { lock (thisLock) { Bitmap clipImage = (Bitmap)data; ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); string strCodecToUse = null; ImageCodecInfo codecToUse = null; EncoderParameters encParams = null; switch (int.Parse(myOptions["SelectedFormat"])) { case 0: anigifTotalFrameNum = int.Parse(myOptions["AniGIFNumFrames"]); strCodecToUse = "AniGIF"; break; case 1: strCodecToUse = "BMP"; break; case 2: encParams = new EncoderParameters(2); encParams.Param[0] = new EncoderParameter(Encoder.Quality, long.Parse(myOptions["JPEGQuality"])); if (bool.Parse(myOptions["JPEGEncoding"])) { encParams.Param[1] = new EncoderParameter(Encoder.RenderMethod, (long)EncoderValue.RenderProgressive); } else { encParams.Param[1] = new EncoderParameter(Encoder.RenderMethod, (long)EncoderValue.RenderNonProgressive); } strCodecToUse = "JPEG"; break; case 3: strCodecToUse = "GIF"; break; case 4: switch (int.Parse(myOptions["TIFFCompression"])) { case 0: encParams = new EncoderParameters(1); encParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone); break; case 1: encParams = new EncoderParameters(2); encParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT3); encParams.Param[1] = new EncoderParameter(Encoder.ColorDepth, 1L); break; case 2: encParams = new EncoderParameters(2); encParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4); encParams.Param[1] = new EncoderParameter(Encoder.ColorDepth, 1L); break; case 3: encParams = new EncoderParameters(1); encParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW); break; case 4: encParams = new EncoderParameters(2); encParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionRle); encParams.Param[1] = new EncoderParameter(Encoder.ColorDepth, 1L); break; } strCodecToUse = "TIFF"; break; case 5: encParams = new EncoderParameters(1); if (bool.Parse(myOptions["PNGEncoding"])) { encParams.Param[0] = new EncoderParameter(Encoder.ScanMethod, (long)EncoderValue.ScanMethodInterlaced); } else { encParams.Param[0] = new EncoderParameter(Encoder.ScanMethod, (long)EncoderValue.ScanMethodNonInterlaced); } strCodecToUse = "PNG"; break; } if (!strCodecToUse.Equals("AniGIF")) { foreach (ImageCodecInfo codec in codecs) { if (codec.FormatDescription.Equals(strCodecToUse)) { codecToUse = codec; break; } } if (codecToUse != null) { string filename = myOptions["PrefixOutputName"] + fileNum + myOptions["SuffixOutputName"] + (codecToUse.FilenameExtension.Split(new char[] { ';' }))[0].Substring(1); clipImage.Save(filename, codecToUse, encParams); fileNum++; } } else { if (!aniGifEnc.IsStarted) { anigifFrameNum = 0; aniGifEnc.Start(myOptions["PrefixOutputName"] + fileNum + myOptions["SuffixOutputName"] + ".gif"); aniGifEnc.SetFrameRate(float.Parse(myOptions["AniGIFFrameRate"])); aniGifEnc.SetRepeat(int.Parse(myOptions["AniGIFRepeat"])); aniGifEnc.SetQuality(int.Parse(myOptions["AniGIFQuality"])); if (!myOptions["AniGIFTrasparent"].Equals("NULL")) { aniGifEnc.SetTransparent(Color.FromArgb(int.Parse(myOptions["AniGIFTrasparent"]))); } } aniGifEnc.AddFrame((Image)clipImage); anigifFrameNum++; MessageBox.Show("Frame " + anigifFrameNum.ToString() + " of " + anigifTotalFrameNum + " added.", "AniGIF Creation", MessageBoxButtons.OK, MessageBoxIcon.Information); if (anigifFrameNum >= anigifTotalFrameNum) { aniGifEnc.Finish(); fileNum++; } } } } catch (System.Runtime.InteropServices.ExternalException ee) { MessageBox.Show("Error writing file.\n" + ee.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (FormatException fe) { MessageBox.Show("Error parsing the configuration file.\n" + fe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// /// </summary> /// <param name="stream"></param> /// <returns></returns> public Stream Create(Stream stream) { coder.Start(stream); Process(); return(stream); }
private void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource) { var processing = FindResource("Encoder.Processing").ToString(); try { switch (param.Type) { case Export.Gif: #region Gif #region Cut/Paint Unchanged Pixels if (param.EncoderType == GifEncoderType.Legacy || param.EncoderType == GifEncoderType.ScreenToGif) { if (param.DetectUnchangedPixels) { Update(id, 0, FindResource("Encoder.Analyzing").ToString()); if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } else { var size = listFrames[0].Path.ScaledSize(); listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height)); } } #endregion switch (param.EncoderType) { case GifEncoderType.ScreenToGif: #region Improved encoding using (var stream = new MemoryStream()) { using (var encoder = new GifFile(stream, param.RepeatCount)) { encoder.UseGlobalColorTable = param.UseGlobalColorTable; encoder.TransparentColor = param.DummyColor; encoder.MaximumNumberColor = param.MaximumNumberColors; for (var i = 0; i < listFrames.Count; i++) { if (!listFrames[i].HasArea && param.DetectUnchangedPixels) { continue; } if (listFrames[i].Delay == 0) { listFrames[i].Delay = 10; } encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Improved Encoding"); } } #endregion break; case GifEncoderType.Legacy: #region Legacy Encoding using (var encoder = new AnimatedGifEncoder()) { if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); encoder.SetTransparent(color); encoder.SetDispose(1); //Undraw Method, "Leave". } encoder.Start(param.Filename); encoder.SetQuality(param.Quality); encoder.SetRepeat(param.RepeatCount); var numImage = 0; foreach (var frame in listFrames) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion if (!frame.HasArea && param.DetectUnchangedPixels) { continue; } var bitmapAux = new Bitmap(frame.Path); encoder.SetDelay(frame.Delay); encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y); bitmapAux.Dispose(); Update(id, numImage, string.Format(processing, numImage)); numImage++; } } #endregion break; case GifEncoderType.PaintNet: #region paint.NET encoding using (var stream = new MemoryStream()) { using (var encoder = new GifEncoder(stream, null, null, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { var bitmapAux = new Bitmap(listFrames[i].Path); encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay)); bitmapAux.Dispose(); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } stream.Position = 0; try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Encoding with paint.Net."); } } #endregion break; default: throw new Exception("Undefined Gif encoder type"); } #endregion break; case Export.Apng: #region Apng #region Cut/Paint Unchanged Pixels if (param.DetectUnchangedPixels) { Update(id, 0, FindResource("Encoder.Analyzing").ToString()); if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.A, param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } else { var size = listFrames[0].Path.ScaledSize(); listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height)); } #endregion #region Encoding using (var stream = new MemoryStream()) { var frameCount = listFrames.Count(x => x.HasArea); using (var encoder = new Apng(stream, frameCount, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { if (!listFrames[i].HasArea && param.DetectUnchangedPixels) { continue; } if (listFrames[i].Delay == 0) { listFrames[i].Delay = 10; } encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Apng Encoding"); } } #endregion #endregion break; case Export.Video: #region Video switch (param.VideoEncoder) { case VideoEncoderType.AviStandalone: #region Avi Standalone var image = listFrames[0].Path.SourceFrom(); if (File.Exists(param.Filename)) { File.Delete(param.Filename); } //1000 / listFrames[0].Delay using (var aviWriter = new AviWriter(param.Filename, param.Framerate, image.PixelWidth, image.PixelHeight, param.VideoQuality)) { var numImage = 0; foreach (var frame in listFrames) { using (var outStream = new MemoryStream()) { var bitImage = frame.Path.SourceFrom(); var enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitImage)); enc.Save(outStream); outStream.Flush(); using (var bitmap = new Bitmap(outStream)) aviWriter.AddFrame(bitmap, param.FlipVideo); } Update(id, numImage, string.Format(processing, numImage)); numImage++; #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } #endregion break; case VideoEncoderType.Ffmpg: #region Video using FFmpeg SetStatus(Status.Encoding, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.Path + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding with FFmpeg.") { HelpLink = str } } ; #endregion break; default: throw new Exception("Undefined video encoder"); } #endregion break; default: throw new ArgumentOutOfRangeException(nameof(param)); } if (!tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Completed, id, param.Filename); } #region Upload if (param.Upload && File.Exists(param.Filename)) { /* * using (var w = new WebClient()) * { * var clientID = "15 digit key"; * w.Headers.Add("Authorization", "Client-ID " + clientID); * var values = new NameValueCollection { { "image", Convert.ToBase64String(File.ReadAllBytes(@""+filename)) }}; * var response = w.UploadValues("https://api.imgur.com/3/upload.xml", values); * var x = XDocument.Load(new MemoryStream(response)); * var link = x.Descendants().Where(n => n.Name == "link").FirstOrDefault(); * string href = link.Value; * } */ } #endregion #region Copy to clipboard if (param.CopyToClipboard && File.Exists(param.Filename)) { Dispatcher.Invoke(() => { try { var data = new DataObject(); switch (param.CopyType) { case CopyType.File: if (param.Type != Export.Video) { data.SetImage(param.Filename.SourceFrom()); } data.SetText(param.Filename, TextDataFormat.Text); data.SetFileDropList(new StringCollection { param.Filename }); break; case CopyType.FolderPath: data.SetText(Path.GetDirectoryName(param.Filename) ?? param.Filename, TextDataFormat.Text); break; case CopyType.Link: data.SetText(param.Filename, TextDataFormat.Text); //TODO: Link. break; default: data.SetText(param.Filename, TextDataFormat.Text); break; } Clipboard.SetDataObject(data, true); InternalSetCopy(id, true); } catch (Exception e) { LogWriter.Log(e, "It was not possible to copy the file."); InternalSetCopy(id, false, e); } }); } #endregion #region Execute commands if (param.ExecuteCommands && !string.IsNullOrWhiteSpace(param.PostCommands)) { var command = param.PostCommands.Replace("{p}", "\"" + param.Filename + "\"").Replace("{f}", "\"" + Path.GetDirectoryName(param.Filename) + "\""); var output = ""; try { foreach (var com in command.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var procStartInfo = new ProcessStartInfo("cmd", "/c " + com) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = new Process()) { process.StartInfo = procStartInfo; process.Start(); var message = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(error)) { throw new Exception(error); } process.WaitForExit(1000); } } InternalSetCommand(id, true, output); } catch (Exception e) { LogWriter.Log(e, "It was not possible to run the post encoding command."); InternalSetCommand(id, false, output, e); } } #endregion } catch (Exception ex) { LogWriter.Log(ex, "Encode"); SetStatus(Status.Error, id, null, false, ex); } finally { #region Delete Encoder Folder try { var encoderFolder = Path.GetDirectoryName(listFrames[0].Path); if (!string.IsNullOrEmpty(encoderFolder)) { if (Directory.Exists(encoderFolder)) { Directory.Delete(encoderFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Cleaning the Encode folder"); } #endregion GC.Collect(); } }
public static async Task ViewModuleAsync(DiscordMessage msg, int id) { //Thread thread = new Thread(delegate () { BaseModule module = GameManager.Instance.CurrentBomb.Modules.First(m => m.ModuleID == id); var panels = module.GetImage(); MemoryStream outStream = new MemoryStream(); string extension; if (panels.Count() == 1) { extension = "png"; var panel = panels.First(); if (panel is SvgDocument) { var bitmap = ((SvgDocument)panel).Draw(); bitmap.Save(outStream, System.Drawing.Imaging.ImageFormat.Png); } else if (panel is Bitmap) { ((Bitmap)panel).Save(outStream, System.Drawing.Imaging.ImageFormat.Png); } else { throw new FormatException(); } } else { extension = "gif"; AnimatedGifEncoder gifEncoder = new AnimatedGifEncoder(); gifEncoder.Start(outStream); gifEncoder.SetDelay(500); gifEncoder.SetRepeat(0); foreach (var panel in panels) { if (panel is SvgDocument) { var p = panel as SvgDocument; gifEncoder.AddFrame(p.Draw()); } else if (panel is Tuple <SvgDocument, int> ) { var p = panel as Tuple <SvgDocument, int>; for (int i = 0; i < p.Item2; i++) { gifEncoder.AddFrame(p.Item1.Draw()); } } else if (panel is Bitmap) { gifEncoder.AddFrame((Bitmap)panel); } else { throw new FormatException(); } } gifEncoder.Finish(); } outStream.Position = 0; var embedBuilder = new DiscordEmbedBuilder().WithTitle($"{module.ModuleName} (#{module.ModuleID})").WithImageUrl(@"attachment://image." + extension); await msg.RespondWithFileAsync(outStream, "image." + extension, content : msg.Author.Mention, embed : embedBuilder.Build()); outStream.Dispose(); //}); //thread.Start(); return; }
private void TransformedEvent(object sender, TransformEventArgs args) { lock (obj) { this.screenindex = args.ScreenIndex; } bool draw = drawBitmap(); if (args.State == TransformEventArgs.BEGIN) { AnimationConfig.AnimateCycleTime = 0; totalBmp = 0; totalBmp++; } else if (args.State == TransformEventArgs.RUNNING) { totalBmp++; } else { int delay = (int)(100 / AnimationConfig.AnimationSpeedFactor); AnimationConfig.AnimateCycleTime = delay * totalBmp; } if (AnimationConfig.IsUseGif) { if (args.State == TransformEventArgs.BEGIN) { String gifFile = AnimationConfig.BitmapSavePath + "/" + AnimationConfig.BitmapSaveName + ".gif"; gifEncoder.Start(gifFile); gifEncoder.AddFrame(bitmap); isStart = true; if (draw) { bmpTool.SaveBitmap(screenindex, bitmap); } } else if (args.State == TransformEventArgs.RUNNING) { gifEncoder.AddFrame(bitmap); if (draw) { bmpTool.SaveBitmap(screenindex, bitmap); } } else if (args.State == TransformEventArgs.END) { gifEncoder.Finish(); //if (bmpTool != null) bmpTool.SaveGif(); isStart = false; if (DrawBitmap != null && !isDisposed) { DrawBitmap(this, new DrawEventArgs(bitmap)); } } else { if (isStart) { gifEncoder.Finish();//if (bmpTool != null) bmpTool.SaveGif(); } isStart = false; } } else { if (DrawBitmap != null && !isDisposed) { DrawBitmap(this, new DrawEventArgs(bitmap)); } } }
// 感谢ok群群友 yuanyilvhua(QQ:4570848**)提供测试电脑,以修复之前存在的高分屏下的bug :-) private void button2_Click(object sender, EventArgs e) { PowerPoint.Selection sel = app.ActiveWindow.Selection; if (sel.Type == PowerPoint.PpSelectionType.ppSelectionSlides && sel.SlideRange.Count > 1) { PowerPoint.Slides slides = app.ActivePresentation.Slides; PowerPoint.SlideRange srange = sel.SlideRange; int scount = srange.Count; float wp = app.ActivePresentation.PageSetup.SlideWidth; float hp = app.ActivePresentation.PageSetup.SlideHeight; int pw = Properties.Settings.Default.pwidth; int h2 = (int)(pw * hp / wp); string name = app.ActivePresentation.Name; if (name.Contains(".pptx")) { name = name.Replace(".pptx", ""); } if (name.Contains(".ppt")) { name = name.Replace(".ppt", ""); } string cPath = app.ActivePresentation.Path + @"\" + name + @" 的GIF图\"; if (!Directory.Exists(cPath)) { Directory.CreateDirectory(cPath); } System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(cPath); int k = dir.GetFiles().Length + 1; string gpath = cPath + name + "_" + k + ".gif"; int time = int.Parse(textBox1.Text.Trim()); int[] index = new int[srange.Count]; for (int i = 1; i <= srange.Count; i++) { index[i - 1] = srange[i].SlideIndex; } if (index[0] > index[1]) { Array.Sort(index); } sel.Unselect(); slides.Range(index).Select(); List <string> path = new List <string>(); for (int i = 1; i <= scount; i++) { PowerPoint.Slide nslide = slides[index[i - 1]]; string cPath2 = cPath + name + "_" + k + ".jpg"; nslide.Export(cPath2, "jpg"); path.Add(cPath2); k = k + 1; } AnimatedGifEncoder gif = new AnimatedGifEncoder(); gif.Start(gpath); gif.SetDelay(time); if (checkBox1.Checked) { gif.SetRepeat(0); } else { gif.SetRepeat(-1); } Bitmap bmp = null; Graphics g = null; for (int j = 0; j < scount; j++) { Image spic = Image.FromFile(path[j]); if (j == 0) { bmp = new Bitmap(spic.Width, spic.Height); bmp.SetResolution(spic.HorizontalResolution, spic.VerticalResolution); g = Graphics.FromImage(bmp); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; } g.Clear(panel1.BackColor); g.DrawImage(spic, 0, 0); gif.AddFrame(bmp); spic.Dispose(); File.Delete(path[j]); } gif.Finish(); g.Dispose(); bmp.Dispose(); if (!checkBox2.Checked) { System.Diagnostics.Process.Start("Explorer.exe", cPath); } else { int n = srange[1].SlideNumber; PowerPoint.Shape nshape = slides[n].Shapes.AddPicture(gpath, Office.MsoTriState.msoFalse, Office.MsoTriState.msoTrue, -pw, 0, pw, h2); if (pw > app.ActivePresentation.PageSetup.SlideWidth) { nshape.LockAspectRatio = Office.MsoTriState.msoTrue; nshape.Width = app.ActivePresentation.PageSetup.SlideWidth; nshape.Left = 0; nshape.Top = 0; } nshape.Select(); File.Delete(gpath); if (dir.GetFiles().Length == 0) { Directory.Delete(cPath, true); } } } else if (sel.Type == PowerPoint.PpSelectionType.ppSelectionShapes) { PowerPoint.Slide slide = app.ActiveWindow.View.Slide; PowerPoint.ShapeRange range = sel.ShapeRange; if (sel.HasChildShapeRange) { range = sel.ChildShapeRange; } int count = range.Count; if (count > 1) { string name = app.ActivePresentation.Name; if (name.Contains(".pptx")) { name = name.Replace(".pptx", ""); } if (name.Contains(".ppt")) { name = name.Replace(".ppt", ""); } string cPath = app.ActivePresentation.Path + @"\" + name + @" 的GIF图\"; if (!Directory.Exists(cPath)) { Directory.CreateDirectory(cPath); } System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(cPath); int k = dir.GetFiles().Length + 1; int time = int.Parse(textBox1.Text.Trim()); string gpath = cPath + name + "_" + k + ".gif"; List <int> w = new List <int>(); List <int> h = new List <int>(); List <string> path = new List <string>(); Bitmap spic = null; float xs = 0; float ys = 0; for (int i = 1; i <= count; i++) { PowerPoint.Shape pic = range[i]; pic.Export(cPath + name + "_" + k + ".png", PowerPoint.PpShapeFormat.ppShapeFormatPNG); spic = new Bitmap(cPath + name + "_" + k + ".png"); w.Add(spic.Width); h.Add(spic.Height); if (xs == 0) { xs = spic.HorizontalResolution; ys = spic.VerticalResolution; } spic.Dispose(); path.Add(cPath + name + "_" + k + ".png"); k = k + 1; } int wmax = w.Max(); int hmax = h.Max(); Bitmap bmp = new Bitmap(wmax, hmax); bmp.SetResolution(xs, ys); Graphics g = Graphics.FromImage(bmp); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; AnimatedGifEncoder gif = new AnimatedGifEncoder(); gif.Start(gpath); gif.SetDelay(time); if (checkBox1.Checked) { gif.SetRepeat(0); } else { gif.SetRepeat(-1); } if (checkBox4.Checked) { gif.SetQuality(300); gif.SetTransparent(panel1.BackColor); } for (int j = 0; j < count; j++) { spic = new Bitmap(path[j]); g.Clear(panel1.BackColor); g.DrawImage(spic, (bmp.Width - spic.Width) / 2, (bmp.Height - spic.Height) / 2); gif.AddFrame(bmp); spic.Dispose(); File.Delete(path[j]); } gif.Finish(); g.Dispose(); bmp.Dispose(); if (!checkBox2.Checked) { System.Diagnostics.Process.Start("Explorer.exe", cPath); } else { PowerPoint.Shape nshape = slide.Shapes.AddPicture(gpath, Office.MsoTriState.msoFalse, Office.MsoTriState.msoTrue, -wmax, 0, wmax, hmax); nshape.Select(); //File.Delete(cPath + name + "_" + k + ".gif"); //if (dir.GetFiles().Length == 0) //{ // Directory.Delete(cPath, true); //} } } else { MessageBox.Show("请选中多张图片"); } } else { MessageBox.Show("请选中多张图片或幻灯片页面"); } }
public void Generate(string method, long seed, long X, long Y, object[] args) { if (!Directory.Exists("terrain")) { Directory.CreateDirectory("terrain"); } IVoxelChannel vc = MakeCopy(); if (TerrainGenerators.ContainsKey(method)) { TerrainGenerators[method].Initialize(mMaterials, seed); TerrainGenerators[method].Generate(ref vc, X, Y); Voxels = (vc as VoxelChannel).Voxels; } else { Console.WriteLine("[TERRAGEN] Terrain generation module \"{0}\" not installed.", method); return; } Image image = new Bitmap(XScale, YScale); double[,] hm = GetDoubles(); for (int x = 0; x < XScale; x++) { for (int y = 0; y < YScale; y++) { int c = (int)(255.0d * (hm[x, y] / 256d)); (image as Bitmap).SetPixel(x, 255 - y, Color.FromArgb(c, c, c)); } } image.Save("terrain/GEN.png", System.Drawing.Imaging.ImageFormat.Png); image.Dispose(); AnimatedGifEncoder e = new AnimatedGifEncoder(); e.Start("terrain/SLICE.gif"); e.SetDelay(250); //-1:no repeat,0:always repeat e.SetRepeat(0); for (int x = 0; x < XScale; x++) { image = new Bitmap(YScale, ZScale); for (int y = 0; y < YScale; y++) { //Console.WriteLine(); for (int z = 0; z < ZScale; z++) { if (IsSolid(x, y, z)) { (image as Bitmap).SetPixel(y, ZScale - z - 1, Color.FromArgb(255, 255, 255)); } else { (image as Bitmap).SetPixel(y, ZScale - z - 1, Color.FromArgb(000, 000, 000)); } } } Console.CursorLeft = 0; Console.Write(" * {0}% ({1}/{2}) frames added...", (int)(((float)(x + 1) / ((float)XScale)) * 100f), x + 1, XScale); e.AddFrame((Image)image.Clone()); image.Dispose(); } Console.WriteLine(); e.Finish(); }
/// <summary> /// Entry method for the console app. /// </summary> /// <param name="args">The arguments.</param> public static void Main(string[] args) { var downloader = new ytgify.Adapters.YoutubeExtractorWrapper.YoutubeExtractorAdapter(); var info2 = downloader.GetVideoInfos(new Uri("https://www.youtube.com/watch?v=FaOSCASqLsE")); downloader.Download(info2.First(), "vidya.mp4"); var adapt = new FFMpegVideoToGifAdapter(); adapt.Convert( @"C:\dev\git\ytgify\ytgifyConsole\bin\Debug\Star Wars Undercover Boss_ Starkiller Base - SNL.mp4", Guid.NewGuid() + ".gif", new GifyRequest { StartTime = new TimeSpan(0, 1, 50), CaptureLengthTime = new TimeSpan(0, 0, 8), }); ////var link = "https://www.youtube.com/watch?v=2a4gyJsY0mc"; var link = "https://www.youtube.com/watch?v=FaOSCASqLsE"; var videoInfos = DownloadUrlResolver.GetDownloadUrls(link); videoInfos = videoInfos.Where(v => v.Resolution > 300).OrderBy(v => v.Resolution); var video = videoInfos.First(info => info.VideoType == VideoType.Mp4); if (video.RequiresDecryption) { DownloadUrlResolver.DecryptDownloadUrl(video); } var fname = video.Title; var badChars = Path.GetInvalidFileNameChars().Where(c => fname.Contains(c)); foreach (var badChar in badChars) { fname = fname.Replace(badChar, '_'); } var videoDownloader = new VideoDownloader(video, Path.Combine(Environment.CurrentDirectory, fname + video.VideoExtension)); videoDownloader.Execute(); var reader = new VideoFileReader(); reader.Open(Path.Combine(Environment.CurrentDirectory, fname + video.VideoExtension)); var framesToSkip = 110 * 23.98; // reader.FrameRate; for (int i = 0; i < framesToSkip; i++) { var fr = reader.ReadVideoFrame(); fr.Dispose(); } var framesToTake = 7 * 23.98; var outputFilePath = Path.Combine(Environment.CurrentDirectory, "screen.gif"); var e = new AnimatedGifEncoder(); e.Start(outputFilePath); e.SetDelay(1000 / 24); e.SetRepeat(0); for (int i = 0; i < framesToTake; i++) { var videoFrame = reader.ReadVideoFrame(); e.AddFrame(videoFrame); videoFrame.Dispose(); } reader.Close(); for (int i = 0; i < framesToTake; i++) { ////e.AddFrame(Image.FromFile(Path.Combine(Environment.CurrentDirectory, "screenie" + i + ".png"))); } e.Finish(); }
private void pictureBox13_Click(object sender, EventArgs e) { Array.Clear(trImg, 0, trImg.Length); Array.Clear(poze, 0, poze.Length); l = 0; /*OpenFileDialog op = new OpenFileDialog(); * op.Multiselect = true; * if (op.ShowDialog() == DialogResult.OK) * { * foreach (string num in op.FileNames) * { * trImg[l] = Image.FromFile(num); * l++; * } * AnimatedGifEncoder s = new AnimatedGifEncoder(); * for (int i = 0; i < l; i++) * { * for (int j = 0; j < trImg[i].GetFrameCount(FrameDimension.Time); j++) * { * trImg[i].SelectActiveFrame(FrameDimension.Time, j); * poze[t2] = (Image)trImg[i].Clone(); * t2++; * } * } * SaveFileDialog sfd = new SaveFileDialog(); * sfd.Filter = "GIF|*.GIF|All files (*.*)|*.*"; * if (sfd.ShowDialog() == DialogResult.OK) * { * s.Start(sfd.FileName); * s.SetDelay(Convert.ToInt32(textBox1.Text)); * s.SetRepeat(0); * for (int i = 0; i < t2; i++) * { * s.AddFrame(poze[i]); * } * s.Finish(); * MessageBox.Show("DONE!"); * } * }*/ OpenFileDialog op = new OpenFileDialog(); op.Multiselect = true; Image temp; if (op.ShowDialog() == DialogResult.OK) { AnimatedGifEncoder s = new AnimatedGifEncoder(); SaveFileDialog sfd = new SaveFileDialog(); sfd.ShowDialog(); s.Start(sfd.FileName); s.SetDelay(Convert.ToInt32(textBox1.Text)); s.SetRepeat(0); foreach (string num in op.FileNames) { Image now; /*temp = Image.FromFile(num); * Bitmap interm = new Bitmap(temp.Width, temp.Height); * Graphics g = Graphics.FromImage(interm); * g.DrawImage(temp, 0, 0); * trImg[l] = interm; * l++;*/ temp = Image.FromFile(num); for (int i = 0; i < temp.GetFrameCount(FrameDimension.Time); i++) { poze[l] = new Bitmap(temp.Width, temp.Height); Graphics g = Graphics.FromImage(poze[l]); temp.SelectActiveFrame(FrameDimension.Time, i); now = (Image)temp.Clone(); g.DrawImage(now, 0, 0); s.AddFrame(poze[l]); l++; } } s.Finish(); MessageBox.Show("GIF-ul a fost creat cu succes!"); /*AnimatedGifEncoder s = new AnimatedGifEncoder(); * for (int i = 0; i < l; i++) * { * for (int j = 0; j < trImg[i].GetFrameCount(FrameDimension.Time); j++) * { * trImg[i].SelectActiveFrame(FrameDimension.Time, j); * poze[t2] = (Image)trImg[i].Clone(); * t2++; * } * } * SaveFileDialog sfd = new SaveFileDialog(); * sfd.Filter = "GIF|*.GIF|All files (*.*)|*.*"; * if (sfd.ShowDialog() == DialogResult.OK) * { * s.Start(sfd.FileName); * s.SetDelay(Convert.ToInt32(textBox1.Text)); * s.SetRepeat(0); * for (int i = 0; i < t2; i++) * { * s.AddFrame(poze[i]); * } * s.Finish(); * MessageBox.Show("DONE!"); * }*/ } }
private void Form1_DragDrop(object sender, DragEventArgs e) { Thread workThread = new Thread(delegate() { string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString(); string dir = System.IO.Path.GetDirectoryName(path);//目錄名稱 string ext = System.IO.Path.GetExtension(path); string nam = System.IO.Path.GetFileNameWithoutExtension(path); if (ext != ".zip") { MessageBox.Show("請拖入zip格式檔案"); } else { this.label1.Text = "正在解壓"; System.Threading.Thread.Sleep(500); ZIP.UnpackFiles(path, dir + "/" + nam); this.label1.Text = "解壓完畢"; System.Threading.Thread.Sleep(500); this.label1.Text = "正在生成GIF"; System.Threading.Thread.Sleep(500); try { string[] jpgImgNames = Directory.GetFiles(dir + "/" + nam); // 获取各帧图片的文件名 string dtStr = DateTime.Now.ToString("yyyyMMddhhmmss"); string outPutPath = string.Format(dir + "/" + nam + ".gif", dtStr); // 生成要保存成的gif图片的文件名 // 创建动画(gif) AnimatedGifEncoder animate = new AnimatedGifEncoder(); animate.Start(outPutPath); animate.SetDelay(delay); animate.SetRepeat(repeat); // -1:不重复,0:无限循环 animate.SetQuality(qua); int filecount = 0; foreach (var item in jpgImgNames) { filecount++; Image imgFrame = Image.FromFile(item); this.label1.Text = "正在添加幀:\r\n" + System.IO.Path.GetFileNameWithoutExtension(item) + "\r\n" + filecount.ToString() + "/" + jpgImgNames.Length.ToString(); animate.AddFrame(imgFrame); // 添加帧 imgFrame.Dispose(); } animate.Finish(); this.label1.Text = "生成成功"; } catch (Exception ex) { this.label1.Text = "出錯啦:" + ex.Message; } try { DirectoryInfo di = new DirectoryInfo(dir + "/" + nam); di.Delete(true); } catch (Exception ex) { this.label1.Text = "出錯啦:" + ex.Message; } } }); workThread.Start(); }
/// <summary> /// Thread method that encodes the list of frames. /// </summary> private void DoWork() { int countList = _listBitmap.Count; var processing = new Processing(); this.Invoke((Action) delegate //Needed because it's a cross thread call. { //Control ctrlParent = panelTransparent; //Processing processing = new Processing(); panelTransparent.Controls.Add(processing); processing.Dock = DockStyle.Fill; processing.SetMaximumValue(countList); processing.SetStatus(1); }); if (Settings.Default.STencodingCustom) // if NGif encoding { #region Ngif encoding int numImage = 0; using (_encoder = new AnimatedGifEncoder()) { _encoder.Start(_outputpath); _encoder.SetQuality(Settings.Default.STquality); _encoder.SetRepeat(Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once try { foreach (var image in _listBitmap) { numImage++; this.BeginInvoke((Action)(() => processing.SetStatus(numImage))); _encoder.SetFrameRate(Convert.ToInt32(numMaxFps.Value)); _encoder.AddFrame(image); } } catch (Exception ex) { LogWriter.Log(ex, "Ngif encoding."); } } #endregion } else //if paint.NET encoding { #region paint.NET encoding //var imageArray = _listBitmap.ToArray(); var delay = 1000 / Convert.ToInt32(numMaxFps.Value); var repeat = (Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once using (var stream = new MemoryStream()) { using (var encoderNet = new GifEncoder(stream, null, null, repeat)) { for (int i = 0; i < _listBitmap.Count; i++) { encoderNet.AddFrame((_listBitmap[i]).CopyImage(), 0, 0, TimeSpan.FromMilliseconds(delay)); this.Invoke((Action)(() => processing.SetStatus(i))); } } stream.Position = 0; using ( var fileStream = new FileStream(_outputpath, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } #endregion } #region Memory Clearing //TODO: Clean the list of delay. listFramesPrivate.Clear(); listFramesUndo.Clear(); listFramesUndoAll.Clear(); listFramesPrivate = null; listFramesUndo = null; listFramesUndoAll = null; _encoder = null; GC.Collect(); //call the garbage colector to empty the memory #endregion #region Finish try { this.Invoke((Action) delegate //must use invoke because it's a cross thread call { _caller.Text = Resources.Title_EncodingDone; _stage = (int)Stage.Stoped; panelTransparent.Controls.Clear(); //Clears the processing page. processing.Dispose(); _caller.Invalidate(); btnRecordPause.Text = Resources.btnRecordPause_Record; btnRecordPause.Image = Properties.Resources.Record; flowPanel.Enabled = true; //_caller.TopMost = false; _caller.TopMost = false; numMaxFps.Enabled = true; tbHeight.Enabled = true; tbWidth.Enabled = true; _caller.MaximizeBox = true; _caller.MinimizeBox = true; _actHook.KeyDown += KeyHookTarget; //Set again the keyboard hook method _actHook.Start(false, true); //start again the keyboard hook watcher }); } catch (Exception ex) { LogWriter.Log(ex, "Invoke error."); } #endregion }
public void CreateGif(List <string> ListOfImagePaths, string PlayerImagesFolder, long ParamPlayerID, ref string Msg, ref bool status, Controller ctrl) { string[] imageFilePaths = ListOfImagePaths.ToArray();// new string[] { "D:\\temp\\01.png", "D:\\temp\\02.png", "D:\\temp\\03.png" }; int MAX_Width = 0; int MAX_Height = 0; foreach (var item in imageFilePaths) { using (Image imgPhoto = Image.FromFile(item)) { //create a image object containing the photograph to watermark int phWidth = imgPhoto.Width; if (MAX_Width < phWidth) { MAX_Width = phWidth; } int phHeight = imgPhoto.Height; if (MAX_Height < phHeight) { MAX_Height = phHeight; } } } string fileNameOnly = Guid.NewGuid().ToString() + ".gif"; string outputFilePath = Path.Combine(PlayerImagesFolder, fileNameOnly); ImageHandler imageHandler = new ImageHandler(); List <Image> ListOfImages = new List <Image>(); int i = 500; foreach (var item in imageFilePaths) { using (Image imgPhoto = Image.FromFile(item)) { //create a image object containing the photograph to watermark Size size = new Size(MAX_Width, MAX_Height); ListOfImages.Add(imageHandler.FixedSize(imgPhoto, size.Width, size.Height)); // ListOfImages.Add(imageHandler.Resize_Usman(imgPhoto, size, PlayerImagesFolder, i)); } i = i + 1; } AnimatedGifEncoder e = new AnimatedGifEncoder(); e.SetSize(MAX_Width, MAX_Height); e.Start(outputFilePath); e.SetDelay(1000); //-1:no repeat,0:always repeat e.SetRepeat(0); foreach (var item in ListOfImages) { e.AddFrame(item); } //for (int i = 0, count = imageFilePaths.Length; i < count; i++) //{ // e.AddFrame(Image.FromFile(imageFilePaths[i])); //} e.Finish(); e.SetDispose(0); /* extract Gif */ //string outputPath = "D:\\temp"; //GifDecoder gifDecoder = new GifDecoder(); //gifDecoder.Read("D:\\temp\\Finalsss.gif"); //for (int i = 0, count = gifDecoder.GetFrameCount(); i < count; i++) //{ // Image frame = gifDecoder.GetFrame(i); // frame i // frame.Save(outputPath + Guid.NewGuid().ToString() + ".png", ImageFormat.Png); //} //Add it to Database PlayerImagesExt PlayerImg = new PlayerImagesExt() { PlayerID = ParamPlayerID, FileName = fileNameOnly, IsAnimated = true, Display = true, DefaultImage = false }; CreateOrUpdate(ref PlayerImg, ref Msg, ref status, ctrl); }
/// <summary> /// 添加图片水印 /// </summary> /// <param name="sourceImage">源图片</param> /// <param name="waterImage">水印图片</param> /// <param name="dissolve">透明度,取值范围1-100,默认值为100(完全不透明)。</param> /// <param name="imagePosition">水印位置</param> /// <param name="distanceX">横轴边距,单位:像素(px),默认值为10。</param> /// <param name="distanceY">纵轴边距,单位:像素(px),默认值为10。</param> /// <param name="watermarkScale">水印图片自适应原图的短边比例,ws的取值范围为0-1。具体是指水印图片保持原比例,并短边缩放到原图短边*ws。</param> /// <param name="watermarkScaleType">水印图片自适应原图的类型,取值0、1、2、3分别表示为自适应原图的短边、长边、宽、高,默认值为0</param> /// <returns>水印图片</returns> public Image SetWaterMark(Image sourceImage, Image waterImage, float dissolve = 100, ImagePosition imagePosition = ImagePosition.RigthBottom, int distanceX = 10, int distanceY = 10, int watermarkScale = 0, int watermarkScaleType = 0) { dissolve = dissolve > 100 ? 100 : dissolve; dissolve = dissolve < 0 ? 0 : dissolve; //水印图片不支持gif if (waterImage.RawFormat.Guid == ImageFormat.Gif.Guid) { throw new Exception("waterImage ImageFormat Gif"); } if (sourceImage.RawFormat.Guid == ImageFormat.Gif.Guid) { string localPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp", Guid.NewGuid().ToString("N")); if (!Directory.Exists(localPath)) { Directory.CreateDirectory(localPath); } //拆分gif string tempGif = Path.Combine(localPath, Guid.NewGuid().ToString("N") + ".gif"); sourceImage.Save(tempGif, ImageFormat.Gif); List <Info> list = new List <Info>(); //历史保存 AnimatedGifDecoder de = new AnimatedGifDecoder(); de.Read(tempGif); var tempRepeat = de.GetLoopCount(); for (int i = 0, count = de.GetFrameCount(); i < count; i++) { Image frame = de.GetFrame(i); string tempPng = Path.Combine(localPath, "sc_" + Guid.NewGuid().ToString("N") + ".png"); frame.Save(tempPng); //图片添加水印 var img = SetWaterMarkByImg(frame, waterImage, dissolve, imagePosition, distanceX, distanceY, watermarkScale, watermarkScaleType); string tempWaterPng = Path.Combine(localPath, "waterImage_" + Guid.NewGuid().ToString("N") + ".png"); img.Save(tempWaterPng); list.Add(new Info { imgDelay = de.GetDelay(i), imgPath = tempWaterPng, }); } //拼接GIF AnimatedGifEncoder e1 = new AnimatedGifEncoder(); e1.Start(tempGif); e1.SetRepeat(tempRepeat); //-1:不循环,0:总是循环 播放 foreach (var info in list) { e1.SetDelay(info.imgDelay); e1.AddFrame(Image.FromFile(info.imgPath)); } e1.Finish(); Image temp = Image.FromFile(tempGif); return(temp); } return(SetWaterMarkByImg(sourceImage, waterImage, dissolve, imagePosition, distanceX, distanceY, watermarkScale, watermarkScaleType)); }
private void RenderToGIF(List <Image> images, string path) { if (string.IsNullOrEmpty(path)) { return; } string outPath = ""; try { outPath = path; if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } DirectoryInfo dir = new DirectoryInfo(outPath); FileInfo[] files = dir.GetFiles(); int i = 0; string name = "Animation"; Top: foreach (FileInfo f in files) { if (f.Name == name + i + ".gif") { i++; goto Top; } } outPath += "\\" + name + i + ".gif"; } catch { // ignored } AnimatedGifEncoder e = new AnimatedGifEncoder(); e.Start(outPath); e.SetDelay(1000 / (int)PlaybackPanel.numFPS.Value); e.SetRepeat(0); e.SetQuality(10); using (ProgressWindow progress = new ProgressWindow(this, "GIF Encoder", "Encoding, please wait...", true)) { progress.TopMost = true; progress.Begin(0, images.Count, 0); for (int i = 0, count = images.Count; i < count; i++) { if (progress.Cancelled) { break; } //GIF transparency support is pretty poor, flickers a lot //e.SetTransparent(ModelPanel.CurrentViewport.BackgroundColor); e.AddFrame(images[i]); progress.Update(progress.CurrentValue + 1); } progress.Finish(); e.Finish(); } _loop = PlaybackPanel.chkLoop.Checked; if (MessageBox.Show(this, "Animated GIF successfully saved to \"" + outPath.Replace("\\", "/") + "\".\nOpen the folder now?", "GIF saved", MessageBoxButtons.YesNo) == DialogResult.Yes) { Process.Start("explorer.exe", path); } }
private void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource) { var processing = FindResource("Encoder.Processing").ToString(); try { switch (param.Type) { case Export.Gif: #region Gif var gifParam = (GifParameters)param; #region Cut/Paint Unchanged Pixels if (gifParam.DetectUnchangedPixels && (gifParam.EncoderType == GifEncoderType.Legacy || gifParam.EncoderType == GifEncoderType.ScreenToGif)) { Update(id, 0, FindResource("Encoder.Analyzing").ToString()); if (gifParam.DummyColor.HasValue) { var color = Color.FromArgb(gifParam.DummyColor.Value.R, gifParam.DummyColor.Value.G, gifParam.DummyColor.Value.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } #endregion switch (gifParam.EncoderType) { case GifEncoderType.ScreenToGif: #region Improved encoding using (var stream = new MemoryStream()) { using (var encoder = new GifFile(stream, gifParam.RepeatCount)) { encoder.UseGlobalColorTable = gifParam.UseGlobalColorTable; encoder.TransparentColor = gifParam.DummyColor; encoder.MaximumNumberColor = gifParam.MaximumNumberColors; for (var i = 0; i < listFrames.Count; i++) { if (!listFrames[i].HasArea) { continue; } if (listFrames[i].Delay == 0) { listFrames[i].Delay = 10; } encoder.AddFrame(listFrames[i].ImageLocation, listFrames[i].Rect, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(gifParam.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) { stream.WriteTo(fileStream); } } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Improved Encoding"); } } #endregion break; case GifEncoderType.Legacy: #region Legacy Encoding using (var encoder = new AnimatedGifEncoder()) { if (gifParam.DummyColor.HasValue) { var color = Color.FromArgb(gifParam.DummyColor.Value.R, gifParam.DummyColor.Value.G, gifParam.DummyColor.Value.B); encoder.SetTransparent(color); encoder.SetDispose(1); //Undraw Method, "Leave". } encoder.Start(gifParam.Filename); encoder.SetQuality(gifParam.Quality); encoder.SetRepeat(gifParam.RepeatCount); var numImage = 0; foreach (var frame in listFrames) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion if (!frame.HasArea && gifParam.DetectUnchangedPixels) { continue; } var bitmapAux = new Bitmap(frame.ImageLocation); encoder.SetDelay(frame.Delay); encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y); bitmapAux.Dispose(); Update(id, numImage, string.Format(processing, numImage)); numImage++; } } #endregion break; case GifEncoderType.PaintNet: #region paint.NET encoding using (var stream = new MemoryStream()) { using (var encoder = new GifEncoder(stream, null, null, gifParam.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { var bitmapAux = new Bitmap(listFrames[i].ImageLocation); encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay)); bitmapAux.Dispose(); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } stream.Position = 0; try { using (var fileStream = new FileStream(gifParam.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Encoding with paint.Net."); } } #endregion break; default: throw new Exception("Undefined Gif encoder type"); } #endregion break; case Export.Video: #region Video var videoParam = (VideoParameters)param; switch (videoParam.VideoEncoder) { case VideoEncoderType.AviStandalone: #region Avi Standalone var image = listFrames[0].ImageLocation.SourceFrom(); using (var aviWriter = new AviWriter(videoParam.Filename, 1000 / listFrames[0].Delay, image.PixelWidth, image.PixelHeight, videoParam.Quality)) { var numImage = 0; foreach (var frame in listFrames) { using (var outStream = new MemoryStream()) { var bitImage = frame.ImageLocation.SourceFrom(); var enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitImage)); enc.Save(outStream); outStream.Flush(); using (var bitmap = new Bitmap(outStream)) { aviWriter.AddFrame(bitmap); } } //aviWriter.AddFrame(new BitmapImage(new Uri(frame.ImageLocation))); Update(id, numImage, string.Format(processing, numImage)); numImage++; #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } #endregion break; case VideoEncoderType.Ffmpg: #region Video using FFmpeg SetStatus(Status.Encoding, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } videoParam.Command = string.Format(videoParam.Command, Path.Combine(Path.GetDirectoryName(listFrames[0].ImageLocation), "%d.png"), videoParam.ExtraParameters, videoParam.Framerate, param.Filename); var process = new ProcessStartInfo(Settings.Default.FfmpegLocation) { Arguments = videoParam.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding with FFmpeg.", new Exception(str)); } #endregion break; default: throw new Exception("Undefined video encoder"); } #endregion break; default: throw new ArgumentOutOfRangeException(nameof(param)); } if (!tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Completed, id, param.Filename); } } catch (Exception ex) { LogWriter.Log(ex, "Encode"); SetStatus(Status.Error, id, null, false, ex.Message); } finally { #region Delete Encoder Folder try { var encoderFolder = Path.GetDirectoryName(listFrames[0].ImageLocation); if (!string.IsNullOrEmpty(encoderFolder)) { if (Directory.Exists(encoderFolder)) { Directory.Delete(encoderFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Cleaning the Encode folder"); } #endregion GC.Collect(); } }
private void Encode(List <FrameInfo> listFrames, int id, string fileName, Export type, CancellationTokenSource tokenSource) { if (type == Export.Gif) { #region Gif if (Settings.Default.CustomEncoding) { #region Custom Gif Encoding using (var encoder = new AnimatedGifEncoder()) { string cutFolder = null; #region Cut/Paint Unchanged Pixels if (Settings.Default.DetectUnchanged) { Update(id, 0, "Analizing Unchanged Pixels"); if (Settings.Default.PaintTransparent) { var color = Color.FromArgb(Settings.Default.TransparentColor.R, Settings.Default.TransparentColor.G, Settings.Default.TransparentColor.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); //TODO: Use System.Windows.Media.Color inside the AnimatedGifEncoder. encoder.SetTransparent(color); encoder.SetDispose(1); //Undraw Method, "Leave". } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } #endregion encoder.Start(fileName); encoder.SetQuality(Settings.Default.Quality); encoder.SetRepeat(Settings.Default.Looped ? (Settings.Default.RepeatForever ? 0 : Settings.Default.RepeatCount) : -1); // 0 = Always, -1 once int numImage = 0; foreach (FrameInfo image in listFrames) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Cancelled, id); break; } #endregion var bitmapAux = new Bitmap(image.ImageLocation); encoder.SetDelay(image.Delay); encoder.AddFrame(bitmapAux, image.PositionTopLeft.X, image.PositionTopLeft.Y); bitmapAux.Dispose(); Update(id, numImage, "Processing " + numImage); numImage++; } #region Specific Clear try { if (!String.IsNullOrEmpty(cutFolder)) { if (Directory.Exists(cutFolder)) { Directory.Delete(cutFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Errow while Deleting and Cleaning Specific Variables"); } #endregion } #endregion } else { #region paint.NET encoding //0 = Always, -1 = no repeat, n = repeat number (first shown + repeat number = total number of iterations) var repeat = (Settings.Default.Looped ? (Settings.Default.RepeatForever ? 0 : Settings.Default.RepeatCount) : -1); using (var stream = new MemoryStream()) { using (var encoderNet = new GifEncoder(stream, null, null, repeat)) { for (int i = 0; i < listFrames.Count; i++) { var bitmapAux = new Bitmap(listFrames[i].ImageLocation); encoderNet.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay)); bitmapAux.Dispose(); Update(id, i, "Processing " + i); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Cancelled, id); break; } #endregion } } stream.Position = 0; try { using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Error while writing to disk."); } } #endregion } #endregion } else { #region Avi var image = listFrames[0].ImageLocation.SourceFrom(); using (var aviWriter = new AviWriter(fileName, 1000 / listFrames[0].Delay, (int)image.PixelWidth, (int)image.PixelHeight, 5000)) { int numImage = 0; foreach (FrameInfo frame in listFrames) { using (MemoryStream outStream = new MemoryStream()) { var bitImage = frame.ImageLocation.SourceFrom(); var enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitImage)); enc.Save(outStream); outStream.Flush(); using (var bitmap = new Bitmap(outStream)) { aviWriter.AddFrame(bitmap); } } //aviWriter.AddFrame(new BitmapImage(new Uri(frame.ImageLocation))); Update(id, numImage, "Processing " + numImage); numImage++; #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Cancelled, id); break; } #endregion } } #endregion } #region Delete Encoder Folder try { var encoderFolder = Path.GetDirectoryName(listFrames[0].ImageLocation); if (!String.IsNullOrEmpty(encoderFolder)) { if (Directory.Exists(encoderFolder)) { Directory.Delete(encoderFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Errow while deleting and cleaning the Encode folder"); } #endregion GC.Collect(); if (!tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Completed, id, fileName); } }
private void TasKSaveImageGif(string pathfile) { if (ImagenList.Count == 0 || ImagenList == null) { return; } Debug.WriteLine("Iniciando ... taskSaveImageGif()"); try { ImageU imgu; List <ImageU> ImagenRedim = new List <ImageU>(); string dir = Path.GetTempPath(); string nametemp = Path.GetTempFileName(); int wd = Imagen.Width; int hd = Imagen.Height; for (int i = 0; i < ImagenList.Count; i++) { nametemp = Path.Combine(dir, Path.GetTempFileName()); imgu = ImagenList[i]; if (imgu.Format == Format.GIF) { using (Image img = Image.FromFile(imgu.Name, true)) { var dimension = new FrameDimension(img.FrameDimensionsList[0]); img.SelectActiveFrame(dimension, imgu.Value); using (MemoryStream ms = new MemoryStream()) { img.Save(ms, ImageFormat.Jpeg); Image imgp = Image.FromStream(ms); Image imgpaso = Utility.ResizeImage(imgp, wd, hd, true); imgpaso.Save(nametemp + ".jpg", ImageFormat.Jpeg); ImageU paso = new ImageU(nametemp + ".jpg", Format.GIF, 0); ImagenRedim.Add(paso); imgpaso.Dispose(); imgp.Dispose(); } } } if (imgu.Format == Format.JPG) { using (Image img = Image.FromFile(imgu.Name, true)) { Image imgpaso = Utility.ResizeImage(img, wd, hd, true); imgpaso.Save(nametemp + ".jpg", ImageFormat.Jpeg); ImageU paso = new ImageU(nametemp + ".jpg", Format.JPG, 0); ImagenRedim.Add(paso); imgpaso.Dispose(); } } } AnimatedGifEncoder egif = new AnimatedGifEncoder(); egif.Start(pathfile); egif.SetDelay(Time); egif.SetRepeat(0); for (int i = 0; i < ImagenRedim.Count; i++) { using (var stream = File.Open(ImagenRedim[i].Name, FileMode.Open)) { egif.AddFrame(Image.FromStream(stream)); } //añadirla. } egif.Finish(); for (int i = 0; i < ImagenRedim.Count; i++) { File.Delete(ImagenRedim[i].Name); } } catch (Exception ex) { Debug.WriteLine( "Error type: " + ex.GetType().ToString() + "\nMessage: " + ex.Message + "\nError in " + MethodBase.GetCurrentMethod().Name + "\n" ); } Debug.WriteLine("Finalizada la construccion del Gif: " + pathfile); }
private void RenderToGIF(Image[] images) { string outPath = ""; Start: if (!String.IsNullOrEmpty(ScreenCapBgLocText.Text)) { try { outPath = ScreenCapBgLocText.Text; if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } DirectoryInfo dir = new DirectoryInfo(outPath); FileInfo[] files = dir.GetFiles(); int i = 0; string name = "BrawlboxAnimation"; Top: foreach (FileInfo f in files) { if (f.Name == name + i + ".gif") { i++; goto Top; } } outPath += "\\" + name + i + ".gif"; } catch { } } else { ScreenCapBgLocText.Text = Application.StartupPath + "\\ScreenCaptures"; goto Start; } AnimatedGifEncoder e = new AnimatedGifEncoder(); e.Start(outPath); e.SetDelay(1000 / (int)pnlPlayback.numFPS.Value); e.SetRepeat(0); e.SetQuality(1); using (ProgressWindow progress = new ProgressWindow(this, "GIF Encoder", "Encoding, please wait...", true)) { progress.TopMost = true; progress.Begin(0, images.Length, 0); for (int i = 0, count = images.Length; i < count; i++) { if (progress.Cancelled) { break; } e.AddFrame(images[i]); progress.Update(progress.CurrentValue + 1); } progress.Finish(); e.Finish(); } if (InterpolationEditor != null) { InterpolationEditor.Enabled = true; } ModelPanel.Enabled = true; Enabled = true; MessageBox.Show("GIF successfully saved to " + outPath.Replace("\\", "/")); }
private void bgdWorker_DoWork(object sender, DoWorkEventArgs e) { //get pollutant type int type = 1; switch ((e.Argument as string[])[0]) { case "SO2": type = 1; break; case "CO": type = 2; break; case "O3": type = 3; break; case "PM10": type = 4; break; case "NO2": type = 7; break; case "PM2.5": type = 33; break; } //count process TimeSpan ts = new TimeSpan(); ts = endDate - currentDate; int totalPic = (int)(ts.TotalHours + 0.5); if (bool.Parse((e.Argument as string[])[1])) { totalPic = (int)(totalPic * 1.5); } float counter = 0; try { do { string url = ""; switch (mapType) { case 0: url = "http://taqm.epa.gov.tw/taqm/chart/Pollutant/map.aspx?param=" + type + "&dt=" + currentDate.ToString("yyyy/MM/dd HH:00"); if (type == 4) { url = "http://taqm.epa.gov.tw/taqm/chart/MainParams24H/map.aspx?param=" + type + "&dt=" + currentDate.ToString("yyyy/MM/dd HH:00"); } break; case 1: url = "http://taqm.epa.gov.tw/taqm/map_Contour/" + currentDate.ToString("yyyyMMdd-HH") + "-0-" + type + ".jpg"; break; } HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); using (HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse()) { using (Stream stream = httpWebReponse.GetResponseStream()) { Image img = Image.FromStream(stream); string filename = path + @"\" + (e.Argument as string[])[0] + "-" + currentDate.AddHours(1).ToString("yyyy-MM-dd HH00") + ".jpg"; imgFiles.Add(filename); img.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg); } } counter += 1; bgdWorker.ReportProgress((int)(counter / totalPic * 100), (e.Argument as string[])[0] + "-" + currentDate.AddHours(1).ToString("yyyy-MM-dd HH00") + ".jpg"); currentDate = currentDate.AddHours(1); if (bgdWorker.CancellationPending) { e.Cancel = true; return; } } while (currentDate <= endDate); //create gif if (bool.Parse((e.Argument as string[])[1])) { bgdWorker.ReportProgress((int)(counter / totalPic * 100), "Generating Gif file..."); AnimatedGifEncoder aniGif = new AnimatedGifEncoder(); string gifName = path + @"\" + (e.Argument as string[])[0] + "-" + dtpStart.Value.ToString("yyyyMMdd HHmm") + "-" + dtpEnd.Value.ToString("yyyyMMdd HHmm") + ".gif"; if (File.Exists(gifName)) { if (MessageBox.Show("File \"" + gifName + "\" already exist, do you want to replace?", "Alert", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.No) { return; } else { File.Delete(gifName); } } aniGif.Start(gifName); aniGif.SetDelay(interval); if (bool.Parse((e.Argument as string[])[2])) { aniGif.SetRepeat(0); } else { aniGif.SetRepeat(-1); } int frameCount = 0; foreach (string imgFile in imgFiles) { if (bgdWorker.CancellationPending) { e.Cancel = true; return; } aniGif.AddFrame(Image.FromFile(imgFile)); counter += 0.5F; frameCount += 1; bgdWorker.ReportProgress((int)(counter / totalPic * 100), "Generating Gif file(" + frameCount + "/" + imgFiles.Count + ")..."); } aniGif.Finish(); //del jpg if (bool.Parse((e.Argument as string[])[3])) { bgdWorker.ReportProgress(99, "Deleting Jpg files..."); try { foreach (string imgFile in imgFiles) { if (File.Exists(imgFile)) { File.Delete(imgFile); } } } catch (Exception ex2) { } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private async void Encode(ProjectInfo project, int id, Parameters param, CancellationTokenSource tokenSource) { var processing = this.DispatcherStringResource("Encoder.Processing"); var listFrames = project.Frames; try { switch (param.Type) { case Export.Gif: #region Gif switch (param.EncoderType) { case GifEncoderType.ScreenToGif: #region Improved encoding using (var stream = new MemoryStream()) { using (var encoder = new GifFile(stream, param.RepeatCount)) { encoder.UseGlobalColorTable = param.UseGlobalColorTable; encoder.TransparentColor = param.DummyColor; encoder.MaximumNumberColor = param.MaximumNumberColors; for (var i = 0; i < listFrames.Count; i++) { encoder.AddFrame(listFrames[i].FullPath, project.FrameSize, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Improved Encoding"); } } #endregion break; case GifEncoderType.Legacy: #region Legacy Encoding using (var encoder = new AnimatedGifEncoder()) { if (param.DummyColor.HasValue) { encoder.SetTransparent(param.DummyColor.Value); encoder.SetDispose(1); //Undraw Method, "Leave". } encoder.Start(param.Filename); encoder.SetQuality(param.Quality); encoder.SetRepeat(param.RepeatCount); var numImage = 0; foreach (var frame in listFrames) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion var bitmapAux = new Bitmap(frame.FullPath); encoder.SetDelay(frame.Delay); encoder.AddFrame(bitmapAux, project.FrameSize.X, project.FrameSize.Y); bitmapAux.Dispose(); Update(id, numImage, string.Format(processing, numImage)); numImage++; } } #endregion break; case GifEncoderType.PaintNet: #region paint.NET encoding using (var stream = new MemoryStream()) { using (var encoder = new GifEncoder(stream, null, null, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { var bitmapAux = new Bitmap(listFrames[i].FullPath); encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay)); bitmapAux.Dispose(); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } stream.Position = 0; try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Encoding with paint.Net."); } } #endregion break; case GifEncoderType.FFmpeg: #region FFmpeg encoding SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.FullPath + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].FullPath) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding the gif with FFmpeg.") { HelpLink = $"Command:\n\r{param.Command}\n\rResult:\n\r{str}" } } ; #endregion break; case GifEncoderType.Gifski: #region Gifski encoding SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsGifskiPresent()) { throw new ApplicationException("Gifski not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } var gifski = new GifskiInterop(); var handle = gifski.Start(UserSettings.All.GifskiQuality, UserSettings.All.Looped); ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(500); SetStatus(Status.Processing, id, null, false); for (var i = 0; i < listFrames.Count; i++) { Update(id, i, string.Format(processing, i)); gifski.AddFrame(handle, (uint)i, listFrames[i].FullPath, listFrames[i].Delay); } gifski.EndAdding(handle); }, null); gifski.End(handle, param.Filename); var fileInfo2 = new FileInfo(param.Filename); if (!fileInfo2.Exists || fileInfo2.Length == 0) { throw new Exception("Error while encoding the gif with Gifski.", new Win32Exception()) { HelpLink = $"Result:\n\r{Marshal.GetLastWin32Error()}" } } ; #endregion break; default: throw new Exception("Undefined Gif encoder type"); } #endregion break; case Export.Apng: #region Apng switch (param.ApngEncoder) { case ApngEncoderType.ScreenToGif: { #region Encoding using (var stream = new MemoryStream()) { var frameCount = listFrames.Count; using (var encoder = new Apng(stream, frameCount, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { encoder.AddFrame(listFrames[i].FullPath, project.FrameSize, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Apng Encoding"); } } #endregion break; } case ApngEncoderType.FFmpeg: { #region FFmpeg encoding SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.FullPath + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].FullPath) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.RepeatCount, param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding the apng with FFmpeg.") { HelpLink = $"Command:\n\r{param.Command}\n\rResult:\n\r{str}" } } ; #endregion break; } } #endregion break; case Export.Video: #region Video switch (param.VideoEncoder) { case VideoEncoderType.AviStandalone: #region Avi Standalone var image = listFrames[0].FullPath.SourceFrom(); if (File.Exists(param.Filename)) { File.Delete(param.Filename); } //1000 / listFrames[0].Delay using (var aviWriter = new AviWriter(param.Filename, param.Framerate, image.PixelWidth, image.PixelHeight, param.VideoQuality)) { var numImage = 0; foreach (var frame in listFrames) { using (var outStream = new MemoryStream()) { var bitImage = frame.FullPath.SourceFrom(); var enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitImage)); enc.Save(outStream); outStream.Flush(); using (var bitmap = new Bitmap(outStream)) aviWriter.AddFrame(bitmap, param.FlipVideo); } Update(id, numImage, string.Format(processing, numImage)); numImage++; #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } #endregion break; case VideoEncoderType.Ffmpg: #region Video using FFmpeg SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.FullPath + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].FullPath) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding with FFmpeg.") { HelpLink = str } } ; #endregion break; default: throw new Exception("Undefined video encoder"); } #endregion break; default: throw new ArgumentOutOfRangeException(nameof(param)); } //If it was canceled, try deleting the file. if (tokenSource.Token.IsCancellationRequested) { if (File.Exists(param.Filename)) { File.Delete(param.Filename); } SetStatus(Status.Canceled, id); return; } #region Execute commands #if !UWP if (param.ExecuteCommands && !string.IsNullOrWhiteSpace(param.PostCommands)) { InternalUpdate(id, "Encoder.Executing", true, true); var command = param.PostCommands.Replace("{p}", "\"" + param.Filename + "\"").Replace("{f}", "\"" + Path.GetDirectoryName(param.Filename) + "\""); var output = ""; try { foreach (var com in command.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var procStartInfo = new ProcessStartInfo("cmd", "/c " + com) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = new Process()) { process.StartInfo = procStartInfo; process.Start(); var message = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(error)) { throw new Exception(error); } process.WaitForExit(1000); } } InternalSetCommand(id, true, command, output); } catch (Exception e) { LogWriter.Log(e, "It was not possible to run the post encoding command."); InternalSetCommand(id, false, command, output, e); } } #endif #endregion if (!tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Completed, id, param.Filename); } } catch (Exception ex) { LogWriter.Log(ex, "Encode"); SetStatus(Status.Error, id, null, false, ex); } finally { #region Delete Encoder Folder try { var encoderFolder = Path.GetDirectoryName(listFrames[0].FullPath); if (!string.IsNullOrEmpty(encoderFolder)) { if (Directory.Exists(encoderFolder)) { Directory.Delete(encoderFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Cleaning the Encode folder"); } #endregion GC.Collect(); } }
// exports image the the full 256-color palette (even those only 3 of the entries are actually used) private async Task ExportFullPalette(string filename) { await Task.Run(() => { try { if (File.Exists(filename)) { File.Delete(filename); } AnimatedGifEncoder e = new AnimatedGifEncoder(); e.Start(filename); e.SetDelay(1000 / 30); //-1:no repeat,0:always repeat e.SetRepeat(0); byte[] scaledPixels = new byte[168 * 96]; for (int frameNum = 0; frameNum < this.Frames.Count(); frameNum++) { this.Cancel.Token.ThrowIfCancellationRequested(); this.CurrentFrame = frameNum + 1; this.Message = String.Format("Exporting frame {0}/{1}...", this.CurrentFrame, this.Frames.Count()); var frame = this.Frames[frameNum]; var palette = new BitmapPalette(new System.Windows.Media.Color[] { GetColor(0, frame), GetColor(128, frame), GetColor(255, frame) }); WriteableBitmap writeable = null; if (this.Angle == 0.0) { var destRect = new Int32Rect(0, 0, 168, 96); writeable = new WriteableBitmap(168, 96, 96, 96, PixelFormats.Indexed8, palette); for (int y = 0; y < 48; y++) { for (int x = 0; x < 84; x++) { var pixel = frame.Pixels[y * 84 + x]; scaledPixels[2 * y * 168 + 2 * x] = scaledPixels[(2 * y + 1) * 168 + 2 * x] = scaledPixels[2 * y * 168 + 2 * x + 1] = scaledPixels[(2 * y + 1) * 168 + 2 * x + 1] = (pixel < 64) ? (byte)0 : (pixel > 190) ? (byte)2 : (byte)1; } } writeable.WritePixels(destRect, scaledPixels, 168, 0); } else if (this.Angle == -90.0) { var destRect = new Int32Rect(0, 0, 96, 168); writeable = new WriteableBitmap(96, 168, 96, 96, PixelFormats.Indexed8, palette); for (int y = 0; y < 84; y++) { for (int x = 0; x < 48; x++) { var pixel = frame.Pixels[x * 84 + (83 - y)]; scaledPixels[2 * y * 96 + 2 * x] = scaledPixels[(2 * y + 1) * 96 + 2 * x] = scaledPixels[2 * y * 96 + 2 * x + 1] = scaledPixels[(2 * y + 1) * 96 + 2 * x + 1] = (pixel < 64) ? (byte)0 : (pixel > 190) ? (byte)2 : (byte)1; } } writeable.WritePixels(destRect, scaledPixels, 96, 0); } else if (this.Angle == 90.0) { var destRect = new Int32Rect(0, 0, 96, 168); writeable = new WriteableBitmap(96, 168, 96, 96, PixelFormats.Indexed8, palette); for (int y = 0; y < 84; y++) { for (int x = 0; x < 48; x++) { var pixel = frame.Pixels[(47 - x) * 84 + y]; scaledPixels[2 * y * 96 + 2 * x] = scaledPixels[(2 * y + 1) * 96 + 2 * x] = scaledPixels[2 * y * 96 + 2 * x + 1] = scaledPixels[(2 * y + 1) * 96 + 2 * x + 1] = (pixel < 64) ? (byte)0 : (pixel > 190) ? (byte)2 : (byte)1; } } writeable.WritePixels(destRect, scaledPixels, 96, 0); } else if (this.Angle == 180.0) { var destRect = new Int32Rect(0, 0, 168, 96); writeable = new WriteableBitmap(168, 96, 96, 96, PixelFormats.Indexed8, palette); for (int y = 0; y < 48; y++) { for (int x = 0; x < 84; x++) { var pixel = frame.Pixels[(47 - y) * 84 + (83 - x)]; scaledPixels[2 * y * 168 + 2 * x] = scaledPixels[(2 * y + 1) * 168 + 2 * x] = scaledPixels[2 * y * 168 + 2 * x + 1] = scaledPixels[(2 * y + 1) * 168 + 2 * x + 1] = (pixel < 64) ? (byte)0 : (pixel > 190) ? (byte)2 : (byte)1; } } writeable.WritePixels(destRect, scaledPixels, 168, 0); } if (writeable != null) { var bitmap = BitmapFromWriteableBitmap(writeable); e.AddFrame(bitmap); } } e.Finish(); this.Success = true; } catch (OperationCanceledException) { } finally { } }); }
private async void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource) { var processing = this.DispatcherStringResource("Encoder.Processing"); try { switch (param.Type) { case Export.Gif: #region Gif #region Cut/Paint Unchanged Pixels if (param.EncoderType == GifEncoderType.Legacy || param.EncoderType == GifEncoderType.ScreenToGif) { if (param.DetectUnchangedPixels) { Update(id, 0, FindResource("Encoder.Analyzing").ToString()); if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } else { var size = listFrames[0].Path.ScaledSize(); listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height)); } } #endregion switch (param.EncoderType) { case GifEncoderType.ScreenToGif: #region Improved encoding using (var stream = new MemoryStream()) { using (var encoder = new GifFile(stream, param.RepeatCount)) { encoder.UseGlobalColorTable = param.UseGlobalColorTable; encoder.TransparentColor = param.DummyColor; encoder.MaximumNumberColor = param.MaximumNumberColors; for (var i = 0; i < listFrames.Count; i++) { if (!listFrames[i].HasArea && param.DetectUnchangedPixels) { continue; } if (listFrames[i].Delay == 0) { listFrames[i].Delay = 10; } encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Improved Encoding"); } } #endregion break; case GifEncoderType.Legacy: #region Legacy Encoding using (var encoder = new AnimatedGifEncoder()) { if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); encoder.SetTransparent(color); encoder.SetDispose(1); //Undraw Method, "Leave". } encoder.Start(param.Filename); encoder.SetQuality(param.Quality); encoder.SetRepeat(param.RepeatCount); var numImage = 0; foreach (var frame in listFrames) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion if (!frame.HasArea && param.DetectUnchangedPixels) { continue; } var bitmapAux = new Bitmap(frame.Path); encoder.SetDelay(frame.Delay); encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y); bitmapAux.Dispose(); Update(id, numImage, string.Format(processing, numImage)); numImage++; } } #endregion break; case GifEncoderType.PaintNet: #region paint.NET encoding using (var stream = new MemoryStream()) { using (var encoder = new GifEncoder(stream, null, null, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { var bitmapAux = new Bitmap(listFrames[i].Path); encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay)); bitmapAux.Dispose(); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } stream.Position = 0; try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Encoding with paint.Net."); } } #endregion break; case GifEncoderType.FFmpeg: #region FFmpeg encoding SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.Path + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding the gif with FFmpeg.") { HelpLink = $"Command:\n\r{param.Command}\n\rResult:\n\r{str}" } } ; #endregion break; case GifEncoderType.Gifski: #region Gifski encoding SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsGifskiPresent()) { throw new ApplicationException("Gifski not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } var gifski = new GifskiInterop(); var handle = gifski.Start(UserSettings.All.GifskiQuality, UserSettings.All.Looped); ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(500); SetStatus(Status.Processing, id, null, false); for (var i = 0; i < listFrames.Count; i++) { Update(id, i, string.Format(processing, i)); gifski.AddFrame(handle, (uint)i, listFrames[i].Path, listFrames[i].Delay); } gifski.EndAdding(handle); }, null); gifski.End(handle, param.Filename); var fileInfo2 = new FileInfo(param.Filename); if (!fileInfo2.Exists || fileInfo2.Length == 0) { throw new Exception("Error while encoding the gif with Gifski.", new Win32Exception()) { HelpLink = $"Command:\n\r{param.Command}\n\rResult:\n\r{Marshal.GetLastWin32Error()}" } } ; #endregion break; default: throw new Exception("Undefined Gif encoder type"); } #endregion break; case Export.Apng: #region Apng #region Cut/Paint Unchanged Pixels if (param.DetectUnchangedPixels) { Update(id, 0, FindResource("Encoder.Analyzing").ToString()); if (param.DummyColor.HasValue) { var color = Color.FromArgb(param.DummyColor.Value.A, param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B); listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource); } else { listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource); } } else { var size = listFrames[0].Path.ScaledSize(); listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height)); } #endregion #region Encoding using (var stream = new MemoryStream()) { var frameCount = listFrames.Count(x => x.HasArea); using (var encoder = new Apng(stream, frameCount, param.RepeatCount)) { for (var i = 0; i < listFrames.Count; i++) { if (!listFrames[i].HasArea && param.DetectUnchangedPixels) { continue; } if (listFrames[i].Delay == 0) { listFrames[i].Delay = 10; } encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay); Update(id, i, string.Format(processing, i)); #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } try { using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096)) stream.WriteTo(fileStream); } catch (Exception ex) { SetStatus(Status.Error, id); LogWriter.Log(ex, "Apng Encoding"); } } #endregion #endregion break; case Export.Video: #region Video switch (param.VideoEncoder) { case VideoEncoderType.AviStandalone: #region Avi Standalone var image = listFrames[0].Path.SourceFrom(); if (File.Exists(param.Filename)) { File.Delete(param.Filename); } //1000 / listFrames[0].Delay using (var aviWriter = new AviWriter(param.Filename, param.Framerate, image.PixelWidth, image.PixelHeight, param.VideoQuality)) { var numImage = 0; foreach (var frame in listFrames) { using (var outStream = new MemoryStream()) { var bitImage = frame.Path.SourceFrom(); var enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitImage)); enc.Save(outStream); outStream.Flush(); using (var bitmap = new Bitmap(outStream)) aviWriter.AddFrame(bitmap, param.FlipVideo); } Update(id, numImage, string.Format(processing, numImage)); numImage++; #region Cancellation if (tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Canceled, id); break; } #endregion } } #endregion break; case VideoEncoderType.Ffmpg: #region Video using FFmpeg SetStatus(Status.Processing, id, null, true); if (!Util.Other.IsFfmpegPresent()) { throw new ApplicationException("FFmpeg not present."); } if (File.Exists(param.Filename)) { File.Delete(param.Filename); } #region Generate concat var concat = new StringBuilder(); foreach (var frame in listFrames) { concat.AppendLine("file '" + frame.Path + "'"); concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture)); } var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath(); var concatFile = Path.Combine(concatPath, "concat.txt"); if (!Directory.Exists(concatPath)) { Directory.CreateDirectory(concatPath); } if (File.Exists(concatFile)) { File.Delete(concatFile); } File.WriteAllText(concatFile, concat.ToString()); #endregion param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename); var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation) { Arguments = param.Command, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardError = true }; var pro = Process.Start(process); var str = pro.StandardError.ReadToEnd(); var fileInfo = new FileInfo(param.Filename); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception("Error while encoding with FFmpeg.") { HelpLink = str } } ; #endregion break; default: throw new Exception("Undefined video encoder"); } #endregion break; default: throw new ArgumentOutOfRangeException(nameof(param)); } //If it was canceled, try deleting the file. if (tokenSource.Token.IsCancellationRequested) { if (File.Exists(param.Filename)) { File.Delete(param.Filename); } SetStatus(Status.Canceled, id); return; } #region Upload if (param.Upload && File.Exists(param.Filename)) { InternalUpdate(id, "Encoder.Uploading", true, true); try { ICloud cloud = CloudFactory.CreateCloud(param.UploadDestinationIndex); var uploadedFile = await cloud.UploadFileAsync(param.Filename, CancellationToken.None); InternalSetUpload(id, true, uploadedFile.Link, uploadedFile.DeleteLink); } catch (Exception e) { LogWriter.Log(e, "It was not possible to run the post encoding command."); InternalSetUpload(id, false, null, null, e); } } #endregion #region Copy to clipboard if (param.CopyToClipboard && File.Exists(param.Filename)) { Dispatcher.Invoke(() => { try { var data = new DataObject(); switch (param.CopyType) { case CopyType.File: if (param.Type != Export.Video) { data.SetImage(param.Filename.SourceFrom()); } data.SetText(param.Filename, TextDataFormat.Text); data.SetFileDropList(new StringCollection { param.Filename }); break; case CopyType.FolderPath: data.SetText(Path.GetDirectoryName(param.Filename) ?? param.Filename, TextDataFormat.Text); break; case CopyType.Link: var link = InternalGetUpload(id); data.SetText(string.IsNullOrEmpty(link) ? param.Filename : link, TextDataFormat.Text); break; default: data.SetText(param.Filename, TextDataFormat.Text); break; } //It tries to set the data to the clipboard 10 times before failing it to do so. //This issue may happen if the clipboard is opened by any clipboard manager. for (var i = 0; i < 10; i++) { try { Clipboard.SetDataObject(data, true); break; } catch (COMException ex) { if ((uint)ex.ErrorCode != 0x800401D0) //CLIPBRD_E_CANT_OPEN { throw; } } Thread.Sleep(100); } InternalSetCopy(id, true); } catch (Exception e) { LogWriter.Log(e, "It was not possible to copy the file."); InternalSetCopy(id, false, e); } }); } #endregion #region Execute commands if (param.ExecuteCommands && !string.IsNullOrWhiteSpace(param.PostCommands)) { InternalUpdate(id, "Encoder.Executing", true, true); var command = param.PostCommands.Replace("{p}", "\"" + param.Filename + "\"").Replace("{f}", "\"" + Path.GetDirectoryName(param.Filename) + "\""); var output = ""; try { foreach (var com in command.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var procStartInfo = new ProcessStartInfo("cmd", "/c " + com) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = new Process()) { process.StartInfo = procStartInfo; process.Start(); var message = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(message)) { output += message + Environment.NewLine; } if (!string.IsNullOrWhiteSpace(error)) { throw new Exception(error); } process.WaitForExit(1000); } } InternalSetCommand(id, true, command, output); } catch (Exception e) { LogWriter.Log(e, "It was not possible to run the post encoding command."); InternalSetCommand(id, false, command, output, e); } } #endregion if (!tokenSource.Token.IsCancellationRequested) { SetStatus(Status.Completed, id, param.Filename); } } catch (Exception ex) { LogWriter.Log(ex, "Encode"); SetStatus(Status.Error, id, null, false, ex); } finally { #region Delete Encoder Folder try { var encoderFolder = Path.GetDirectoryName(listFrames[0].Path); if (!string.IsNullOrEmpty(encoderFolder)) { if (Directory.Exists(encoderFolder)) { Directory.Delete(encoderFolder, true); } } } catch (Exception ex) { LogWriter.Log(ex, "Cleaning the Encode folder"); } #endregion GC.Collect(); } }
// exports image with a 3-color palette private async Task ExportSmallPalette(string filename) { await Task.Run(() => { try { if (File.Exists(filename)) { File.Delete(filename); } AnimatedGifEncoder e = new AnimatedGifEncoder(); e.Start(filename); e.SetDelay(1000 / 30); //-1:no repeat,0:always repeat e.SetRepeat(0); var destRect = new Int32Rect(0, 0, 168, 96); byte[] packedPixels = new byte[168 * 96 / 4]; for (int frameNum = 0; frameNum < this.Frames.Count(); frameNum++) { this.Cancel.Token.ThrowIfCancellationRequested(); this.CurrentFrame = frameNum + 1; this.Message = String.Format("Exporting frame {0}/{1}...", this.CurrentFrame, this.Frames.Count()); var frame = this.Frames[frameNum]; var palette = new BitmapPalette(new System.Windows.Media.Color[] { GetColor(0, frame), GetColor(128, frame), GetColor(255, frame) }); var writeable = new WriteableBitmap(168, 96, 96, 96, PixelFormats.Indexed2, palette); for (int y = 0; y < 48; y++) { for (int x = 0; x < 84; x++) { int color = frame.Pixels[y * 84 + x]; color = (color < 64) ? 0 : (color > 190) ? 2 : 1; SetPackedPixel(packedPixels, 2 * x, 2 * y, color); SetPackedPixel(packedPixels, 2 * x + 1, 2 * y, color); SetPackedPixel(packedPixels, 2 * x, 2 * y + 1, color); SetPackedPixel(packedPixels, 2 * x + 1, 2 * y + 1, color); } } writeable.WritePixels(destRect, packedPixels, 168 / 4, 0); var bitmap = BitmapFromWriteableBitmap(writeable); e.AddFrame(bitmap); } e.Finish(); this.Success = true; } catch (OperationCanceledException) { } finally { } }); }