cannot delete image files in folder. i know it locked and used by another process but i dont know which process holding it and how to unlock the image files so i can delete it. tried to guess by putting .Dispose() method in every loop ending but no luck. >_<
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Net;
using System.Drawing;
using System.IO;
using AForge.Video;
using AForge.Video.VFW; //video recording
namespace example
{
public partial class LiveRecording2 : System.Web.UI.Page
{
AVIWriter writer = new AVIWriter("MSVC");
protected void Page_Load(object sender, EventArgs e)
{
}
private void Get1Image()
{
for (int i = 0; i < 11; i++)
{
string ImagePath = Server.MapPath("~\\Videos\\liveRecording2\\") + string.Format("{0}", i + 1) + ".jpg";
string ip = "http://example.ip.com:portNo/jpeg.cgi";
string sourceURL = ip;
WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("userName", "password");
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
Bitmap bmp = (Bitmap)Bitmap.FromStream(stream);
bmp.Save(ImagePath);
}
}
private void doRecording()
{
string ImagePath = Server.MapPath("~\\Videos\\liveRecording2\\");
string SavingPath = Server.MapPath("~\\Videos\\liveRecording2\\"); //recorded video path
string VideoName = "ICS-" + String.Format("{0:yyyyMMdd_hhmmss}", DateTime.Now) + ".avi";
writer.Open(SavingPath + VideoName, 640, 480); //create an AVI file and open it for images adding
// create frame image
Bitmap image = new Bitmap(320, 240);
//var cubit = new AForge.Imaging.Filters.ResizeBilinear(320, 240);
string[] files = Directory.GetFiles(ImagePath);
writer.FrameRate = 25;
int index = 0;
int failed = 0;
foreach (var item in files)
{
index++;
try
{
image = Image.FromFile(item) as Bitmap;
//image = cubit.Apply(image);
for (int i = 0; i < 5; i++)
{
writer.AddFrame(image);
}
}
catch
{
failed++;
}
//this.Text = index + " of " + files.Length + ". Failed: " + failed;
}
writer.Close();
writer.Dispose();
this.Label1.Text = "status: Video was successfully created";
this.Label2.Text = "Video Path: ~/Videos/liveRecording2/" + VideoName;
DeleteImage();
}
protected void Button1_Click(object sender, EventArgs e)
{
Get1Image();
doRecording();
}
public void DeleteImage()
{
DirectoryInfo di = new DirectoryInfo(Server.MapPath("~\\Videos\\liveRecording2\\"));
FileInfo[] files = di.GetFiles("*.jpg");
//.Where(p => p.Extension == ".jpg").ToArray();
foreach (FileInfo file in files)
{
file.Delete(); // **error here**
}
this.Label3.Text = "Image deleted";
}
}
}
Your problem is probably here:
image = Image.FromFile(item) as Bitmap;
Try wrapping that bit of code in a using:
using(image = Image.FromFile(item) as Bitmap)
{
// rest here
}
Related
I made a video recorder that takes screenshots each frame and saves it in a temporary folder. When I press the Stop recording button it puts it all together in one video. I now need to have my program check the latest 2 screenshots it has taken and compare them to find changes, if change wasn't found the last image should get deleted. In the other hand if the 2 images had any difference, both images would stay there.
Thank you for helping me out!
Forms1.cs[Design]
Below is my Screen Recorder script
ScreenRecorder.cs
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Accord.Video;
using Accord.Video.FFMPEG;
using GroupDocs.Comparison.Options;
using GroupDocs.Comparison;
namespace Timelapser_version_1._2
{
class ScreenRecorder
{
//Video variables:
private Rectangle bounds;
private string outputPath = "";
private string tempPath = "";
private int fileCount = 1;
private List<string> inputImageSequence = new List<string>();
//File variables:
private string audioName = "mic.wav";
private string videoName = "video.mp4";
private string finalName = "FinalVideo.mp4";
//Time variable:
Stopwatch watch = new Stopwatch();
//Audio variables:
public static class NativeMethods
{
[DllImport("winmm.dll", EntryPoint = "mciSendStringA", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int record(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
}
//ScreenRecorder Object:
public ScreenRecorder(Rectangle b, string outPath)
{
//Create temporary folder for screenshots:
CreateTempFolder("tempScreenCaps");
//Set variables:
bounds = b;
outputPath = outPath;
}
//Create temporary folder:
private void CreateTempFolder(string name)
{
//Check if a C or D drive exists:
if (Directory.Exists("D://"))
{
string pathName = $"D://{name}";
Directory.CreateDirectory(pathName);
tempPath = pathName;
}
else
{
string pathName = $"C://Documents//{name}";
Directory.CreateDirectory(pathName);
tempPath = pathName;
}
}
//Change final video name:
public void setVideoName(string name)
{
finalName = name;
}
//Delete all files and directory:
private void DeletePath(string targetDir)
{
string[] files = Directory.GetFiles(targetDir);
string[] dirs = Directory.GetDirectories(targetDir);
//Delete each file:
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
//Delete the path:
foreach (string dir in dirs)
{
DeletePath(dir);
}
Directory.Delete(targetDir, false);
}
//Delete all files except the one specified:
private void DeleteFilesExcept(string targetDir, string excDir)
{
string[] files = Directory.GetFiles(targetDir);
//Delete each file except specified:
foreach (string file in files)
{
if (file != excDir)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
}
}
//Clean up program on crash:
public void cleanUp()
{
if (Directory.Exists(tempPath))
{
DeletePath(tempPath);
}
}
//Return elapsed time:
public string getElapsed()
{
return string.Format("{0:D2}:{1:D2}:{2:D2}", watch.Elapsed.Hours, watch.Elapsed.Minutes, watch.Elapsed.Seconds);
}
//Record video:
public void RecordVideo()
{
//Keep track of time:
watch.Start();
int blac=0;
string a ="screenshot-1+%d";
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
//Add screen to bitmap:
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
//Save screenshot:
string name = tempPath + "//screenshot-" + fileCount + ".png";
bitmap.Save(name, ImageFormat.Png);
inputImageSequence.Add(name);
fileCount++;
//Dispose of bitmap:
bitmap.Dispose();
}
}
//Record audio:
public void RecordAudio()
{
NativeMethods.record("open new Type waveaudio Alias recsound", "", 0, 0);
NativeMethods.record("record recsound", "", 0, 0);
}
//Save audio file:
private void SaveAudio()
{
string audioPath = "save recsound " + outputPath + "//" + audioName;
NativeMethods.record(audioPath, "", 0, 0);
NativeMethods.record("close recsound", "", 0, 0);
}
//Save video file:
public void SaveVideo(int width, int height, int frameRate)
{
using (VideoFileWriter vFWriter = new VideoFileWriter())
{
vFWriter.Open(outputPath + "//"+ videoName, width, height, frameRate, VideoCodec.MPEG4);
//Make each screenshot into a video frame:
foreach (string imageLocation in inputImageSequence)
{
Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
vFWriter.WriteVideoFrame(imageFrame);
imageFrame.Dispose();
}
//Close:
vFWriter.Close();
}
}
//Combine video and audio files:
private void CombineVideoAndAudio(string video, string audio)
{
//FFMPEG command to combine video and audio:
string args = $"/c ffmpeg -i \"{video}\" -i \"{audio}\" -shortest {finalName}";
ProcessStartInfo startInfo = new ProcessStartInfo
{
CreateNoWindow = false,
FileName = "cmd.exe",
WorkingDirectory = outputPath,
Arguments = args
};
//Execute command:
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
public void Stop()
{
//Stop watch:
watch.Stop();
//Video variables:
int width = bounds.Width;
int height = bounds.Height;
int frameRate = 10;
//Save audio:
SaveAudio();
//Save video:
SaveVideo(width, height, frameRate);
//Combine audio and video files:
CombineVideoAndAudio(videoName, audioName);
//Delete the screenshots and temporary folder:
DeletePath(tempPath);
//Delete separated video and audio files:
DeleteFilesExcept(outputPath, outputPath + "\\" + finalName);
}
}
}
forms1.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Timelapser_version_1._2
{
public partial class Timelapser : Form
{
string outputPath = "";
bool folderSelected = false;
string finalVidName = "FinalVideo.mp4";
// Screen recorder object:
ScreenRecorder screenRec = new ScreenRecorder(new Rectangle(), " ");
public Timelapser()
{
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
bool containsMP4 = finalVidName.Contains(".mp4");
if (folderSelected && containsMP4)
{
screenRec.setVideoName(finalVidName);
timer1.Start();
}
else if(!folderSelected && containsMP4)
{
MessageBox.Show("You must select an output Folder before recording","Error");
}
else if (folderSelected && !containsMP4)
{
MessageBox.Show("You must select video name that ends in '.mp4'", "Error");
finalVidName = "FinalVideo.mp4";
}
}
private void Stop_Click(object sender, EventArgs e)
{
timer1.Stop();
screenRec.Stop();
Application.Restart();
}
private void timer1_Tick(object sender, EventArgs e)
{
screenRec.RecordVideo();
screenRec.RecordAudio();
Timelabel.Text = screenRec.getElapsed();
}
private void SelectFolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
folderBrowser.Description = "Select an Output Folder";
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
outputPath = #folderBrowser.SelectedPath;
folderSelected = true;
Rectangle bounds = Screen.FromControl(this).Bounds;
screenRec = new ScreenRecorder(bounds,outputPath);
}
else
{
MessageBox.Show("Please select a folder");
}
}
I found the solution, to be able to check each 2 screenshots we need the function below.
public static List<bool> GetHash(Bitmap bmpSource)
{
List<bool> lResult = new List<bool>();
//create new image with 128x128 pixel
Bitmap bmpMin = new Bitmap(bmpSource, new System.Drawing.Size(128, 128));
for (int j = 0; j < bmpMin.Height; j++)
{
for (int i = 0; i < bmpMin.Width; i++)
{
//reduce colors to true / false
lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.1f);
}
}
return lResult;
}
This function gets the screenshots and creates a 128x128 version of them. Also it changes the colour to black and white to get a true or false.
Then we need to call the function for each 2 screenshots as shown below.
List<bool> iHash1 = GetHash(new Bitmap(tempPath + "//screenshot-" + k + ".png"));
List<bool> iHash2 = GetHash(new Bitmap(tempPath + "//screenshot-" + (k + 1) + ".png"));
//determine the number of equal pixel (x of 256)
long equalElements = iHash1.Zip(iHash2, (i, j) => i == j).Count(eq => eq);
Debug.Write(equalElements);
if (equalElements > 16300 )
{
var filePath = tempPath + "//screenshot-" + (k+1) + ".png";
File.Delete(filePath);
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
namespace DownloadFilesFromSite
{
public partial class Form1 : Form
{
private Queue<string> _downloadUrls = new Queue<string>();
private List<string> urls = new List<string>();
private List<string> sources = new List<string>();
private List<string> links = new List<string>();
public Form1()
{
InitializeComponent();
Sources();
}
private void Sources()
{
string link = "https://www.documentingreality.com/forum/f10/several-different-dead-chinese-women-176102/";
for (int i = 2; i < 141; i++)
{
sources.Add(link + "index" + i + ".html");
}
}
private void ReadSourcePage(string fn)
{
var lines = File.ReadAllLines(fn).ToList();
string contains = "https://www.documentingreality.com/forum/attachments/f10/";
for (int i = 0; i < lines.Count; i++)
{
if (lines[i].Contains(contains))
{
int index = lines[i].IndexOf("f10/") + 4;
int index1 = lines[i].IndexOf(".jpg") - index;
string result = lines[i].Substring(index, index1);
links.Add(contains + result + ".jpg");
}
}
}
private void downloadFiles(IEnumerable<string> urls)
{
foreach (var url in urls)
{
_downloadUrls.Enqueue(url);
}
// Starts the download
button1.Text = "Downloading...";
button1.Enabled = false;
progressBar1.Visible = true;
label1.Visible = true;
DownloadFile();
}
private void DownloadFile()
{
if (_downloadUrls.Any())
{
WebClient client = new WebClient();
client.Headers.Add("User-Agent: Other");
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFileCompleted += client_DownloadFileCompleted;
var url = _downloadUrls.Dequeue();
string FileName = url.Substring(url.LastIndexOf("/") + 1,
(url.Length - url.LastIndexOf("/") - 1));
client.DownloadFileAsync(new Uri(url), #"E:\dr\htmlsources\" + FileName);
label1.Text = url;
return;
}
// End of the download
button1.Text = "Download Complete";
}
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
// handle error scenario
throw e.Error;
}
if (e.Cancelled)
{
// handle cancelled scenario
}
DownloadFile();
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
downloadFiles(sources);
}
}
}
In the DownloadFile on the line :
client.DownloadFileAsync(new Uri(url), #"E:\dr\htmlsources\" + FileName);
If I copy the url address to the chrome it will show me the source of the page and I can save and download the source page it will be about 700KB
But when clicking the button1 when it start downloading this sources it will throw exception :
ArgumentOutOfRangeException: Value of '-154300' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.
Parameter name: Value
And if I will not use the progressBar1 at all for testing all the downloaded sources files will be about 25KB instead about 700KB.
I tried to add the line :
client.Headers.Add("User-Agent: Other");
But not seems to fix the exception.
DownloadFileAsync will return immediately and then 'client' will also go out of scope. Read up on how to use async/await functions.
Hello I have created a program that contains a btnCopy associated with a copyfiledialog, I would like to know why when I press the btnCopy it copies me several files at the same time, I would like that it copies the files one after the other, can will you help me?
private void btnCopy_Click(object sender,EventArgs e)
{
string sourceDir = #"C:\Users\PORTABLEHP\Documents";
string destDir = #"C:\Users\PORTABLEHP\Documents\xgen";
try
{
string [] txtList = Directory.GetFiles(sourceDir,"*.txt");
foreach (string f in txtList)
{
try
{
string fName = f.Substring(sourceDir.Length + 1);
string [] files = new string[sourceDir.Length];
progressBar1.Value = 1;
progressBar1.Minimum = 0;
progressBar1.Maximum = files.Length;
for(int i = 1;i < files.Length; i++)
{
progressBar1.PerformStep();
File.Copy(Path.Combine(sourceDir,fName),
Path.Combine(destDir,fName), true);
}
}
catch(IOException copyerror)
{
MessageBox.Show(copyerror.Message)
}
,
Try this:
using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.VisualBasic.FileIO;
public partial class Form1 : Form
{
// other code
private void button1_Click(object sender, EventArgs e)
{
string sourceDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string destDir = Path.Combine(sourceDir, "xgen");
string[] txtList =
Directory.GetFiles(sourceDir, "*.txt");
progressBar1.Value = 1;
progressBar1.Minimum = 0;
progressBar1.Maximum = txtList.Length;
try
{
foreach (string f in txtList)
{
string fName = Path.GetFileName(f); //f.Substring(sourceDir.Length + 1);
string destFile = Path.Combine(destDir, fName);
FileSystem.CopyFile(
f, destFile, UIOption.AllDialogs, UICancelOption.ThrowException);
progressBar1.PerformStep();
}
}
catch (IOException copyerror)
{
MessageBox.Show(copyerror.Message);
}
}
}
Note that you need to add a reference to Microsoft.VisualBasic to gain access to FileSystem.CopyFile() which copies with the standard windows UI.
I'm looking to take a screenshot from a web page that is streaming from an IP camera and as such doesn't triggerWebBrowserReadyState.Complete.
The webpage in question is literally streaming a mjpeg and the browser is always loading/streaming.
I can generate images for other URLs but cannot guess this to give anything other than 'Navigation Cancelled'.
I have tried WebBrowser.Stop() but to no avail...
The webpage is simply an mJpeg:
<img class"shrink" src="192.168.1.124/Streaming/channels/1/httpPreview"; alt="192.168.1.124/Streaming/channels/1/httpPreview"; class="shrinkToFit" height="148" width="217"> </img>
using Telegram.Bot;
using System.Threading.Tasks;
using System.IO;
using Telegram.Bot.Types;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace Telegram_Alerter
{
public static class BitmapExtensions
{
public static void SaveJPG100(this Bitmap bmp, string filename)
{
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
bmp.Save(filename, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static void SaveJPG100(this Bitmap bmp, Stream stream)
{
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
bmp.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
var codecs = ImageCodecInfo.GetImageDecoders();
foreach (var codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
// Return
return null;
}
}
class Program
{
static public void Main(string[] args)
{
TelegramMessageAsync().Wait();
}
static public async Task TelegramMessageAsync()
{
TelegramBotClient Bot = new TelegramBotClient("<mykey>");
WebsiteToImage websiteToImage = new WebsiteToImage("http://192.168.1.124/Streaming/channels/1/httpPreview", Application.StartupPath + "file.jpg");
websiteToImage.Generate();
using (FileStream fs = System.IO.File.OpenRead(Application.StartupPath + "file.jpg"))
{
FileToSend fts = new FileToSend();
fts.Content = fs;
fts.Filename = "file.jpg";
await Bot.SendPhotoAsync(<bot>, fts, "message here");
}
}
public class WebsiteToImage
{
private Bitmap m_Bitmap;
private string m_Url;
private string m_FileName = string.Empty;
public WebsiteToImage(string url)
{
// Without file
m_Url = url;
}
public WebsiteToImage(string url, string fileName)
{
// With file
m_Url = url;
m_FileName = fileName;
}
public Bitmap Generate()
{
// Thread
var m_thread = new Thread(_Generate);
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
return m_Bitmap;
}
private void _Generate()
{
var browser = new WebBrowser { ScrollBarsEnabled = false };
browser.Navigate(m_Url);
browser.DocumentCompleted += WebBrowser_DocumentCompleted;
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
browser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Capture
var browser = (WebBrowser)sender;
browser.ClientSize = new Size(1024,768);
browser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(1024,768);
browser.BringToFront();
browser.DrawToBitmap(m_Bitmap, browser.Bounds);
// Save as file?
if (m_FileName.Length > 0)
{
// Save
m_Bitmap.SaveJPG100(m_FileName);
}
}
}
}
}
Maybe that Page contains Iframes that never load.If yes:
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// to check if it is not Iframe
if (e.Url.AbsolutePath != this.webBrowser.Url.AbsolutePath)
{
// Capture
var browser = (WebBrowser)sender;
browser.ClientSize = new Size(1024,768);
browser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(1024,768);
browser.BringToFront();
browser.DrawToBitmap(m_Bitmap, browser.Bounds);
// Save as file?
if (m_FileName.Length > 0)
{
// Save
m_Bitmap.SaveJPG100(m_FileName);
}
}
}
Thanks for the efforts but I answered the question by using an FFMpeg .NET wrapper called N.Reco meaning I did not have to worry about parsing the MJPEG to obtain a single frame and then convert to a JPEG.
This was achieved in two lines of code but FFMPEG does add 20Mb to your application.
var ffmpeg = new NReco.VideoConverter.FFMpegConverter();
ffmpeg.GetVideoThumbnail(pathToVideoFile, Application.StartupPath + stamp);
The error is on the line:
for (int x = 0; x < myList.Count(); x++)
The x++is painted with green.
Im using backgroundoworker and I used this code same code in another form before without a backgroundworker and it worked good. Now in the other form im using a click button event to show() this form and I want to use a progressBar1 to show the progress of the backgroundowrker work.
I used now try and catch inside this for loop and it went to the catch point and showed me the error. The full exception message is:
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at mws.Animation_Radar_Preview.backGroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in D:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\Animation_Radar_Preview.cs:line 163
gifImages isnt null.
This is the full code of this form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using unfreez_wrapper;
namespace mws
{
public partial class Animation_Radar_Preview : Form
{
int mtpStart;
int mtpEnd;
Picturebox1_Fullscreen pb1;
string radar_images_download_directory;
string tempRadarPngToGifDirectory;
int numberOfFiles;
UnFreezWrapper unfreez;
string path_exe;
List<string> myList;
string previewDirectory;
int animatedGifSpeed;
bool loop;
string nameOfStartFile;
string nameOfEndFile;
string previewFileName;
BackgroundWorker backGroundWorker1;
Image img;
private MemoryStream _memSt = null;
public Animation_Radar_Preview()
{
InitializeComponent();
mtpStart = Picturebox1_Fullscreen.mtp1Start;
mtpEnd = Picturebox1_Fullscreen.mtp1End;
animatedGifSpeed = Picturebox1_Fullscreen.animatedSpeed;
loop = Picturebox1_Fullscreen.looping;
pb1 = new Picturebox1_Fullscreen();
radar_images_download_directory = Options_DB.Get_Radar_Images_Download_Directory();
path_exe = Path.GetDirectoryName(Application.LocalUserAppDataPath);
tempRadarPngToGifDirectory = path_exe + "\\" + "tempRadarPngToGifDirectory";
if (Directory.Exists(tempRadarPngToGifDirectory))
{
}
else
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
previewDirectory = path_exe + "\\" + "previewDirectory";
if (Directory.Exists(previewDirectory))
{
}
else
{
Directory.CreateDirectory(previewDirectory);
}
previewFileName = previewDirectory + "\\" + "preview.gif";
loop = false;
animatedGifSpeed = 0;
unfreez = new UnFreezWrapper();
backGroundWorker1 = new BackgroundWorker();
backGroundWorker1.WorkerSupportsCancellation = true;
this.backGroundWorker1.WorkerReportsProgress = true;
backGroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backGroundWorker1_ProgressChanged);
backGroundWorker1.DoWork += new DoWorkEventHandler(backGroundWorker1_DoWork);
backGroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backGroundWorker1_RunWorkerCompleted);
backGroundWorker1.RunWorkerAsync();
progressBar1.Value = 0;
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult result1;
result1 = new DialogResult();
SaveFileDialog sd = new SaveFileDialog();
sd.Title = "Select a folder to save the animated gif to";
sd.InitialDirectory = "c:\\";
sd.FileName = null;
sd.Filter = "Gif File|*.gif;*.jpg|Gif|*.gif";
sd.FilterIndex = 1;
sd.RestoreDirectory = true;
result1 = sd.ShowDialog();
string file1 = sd.FileName;
if (result1 == DialogResult.OK)
{
File.Move(previewFileName, file1);
}
}
public void pictureBoxImage(string pbImage)
{
Image img2 = null;
try
{
using (img = Image.FromFile(pbImage))
{
//get the old image thats loaded from the _memSt memorystream
//and dispose it
Image i = this.pictureBox1.Image;
this.pictureBox1.Image = null;
if (i != null)
i.Dispose();
//grab the old stream
MemoryStream m = _memSt;
//save the new image to this stream
_memSt = new MemoryStream();
img.Save(_memSt, System.Drawing.Imaging.ImageFormat.Gif);
if (m != null)
m.Dispose();
//create our image to display
img2 = Image.FromStream(_memSt);
}
if (img2 != null)
pictureBox1.Image = img2;
label2.Text = numberOfFiles.ToString();
label6.Text = nameOfStartFile.ToString();
label4.Text = nameOfEndFile.ToString();
//File.Delete(pbImage);
}
catch(Exception err)
{
Logger.Write("Animation Error >>> " + err);
}
}
private void backGroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backGroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
List<string> myGifList;
Image gifImages = null;
//button1.Enabled = false;
Animation_Radar_Preview ap = new Animation_Radar_Preview();
//ap.FormClosing += new FormClosingEventHandler(ap_FormClosing);
FileInfo[] fi;
DirectoryInfo dir1 = new DirectoryInfo(radar_images_download_directory);
fi = dir1.GetFiles("*.png");
myList = new List<string>();
myGifList = new List<string>();
for (int i = mtpStart; i < mtpEnd; i++)
{
myList.Add(fi[i].FullName);
}
for (int x = 0; x < myList.Count(); x++)
{
try
{
gifImages = Image.FromFile(myList[x]);
gifImages.Save(tempRadarPngToGifDirectory + "\\" + x.ToString("D6") + ".Gif", System.Drawing.Imaging.ImageFormat.Gif);
}
catch (Exception ex)
{
MessageBox.Show(x.ToString() + "\r\n" + (gifImages == null).ToString() + "\r\n" + ex.Message);
}
}
myGifList = new List<string>();
dir1 = new DirectoryInfo(tempRadarPngToGifDirectory);
fi = dir1.GetFiles("*.gif");
nameOfStartFile = fi[0].Name;
for (int i = 0; i < fi.Length; i++)
{
myGifList.Add(fi[i].FullName);
//backGroundWorker1.ReportProgress(i);
nameOfEndFile = fi[i].Name.Length.ToString();
}
numberOfFiles = myGifList.Count();
unfreez.MakeGIF(myGifList, previewFileName, animatedGifSpeed, loop);
/*this.Invoke((MethodInvoker)delegate
{
pictureBoxImage(previewFileName);
});*/
}
private void backGroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pictureBoxImage(previewFileName);
}
}
}
I'm not entirely sure what is going wrong, especially as you say this same code worked previously — but it is not clear whether it worked with the same set of images.
Anyhow, the documentation for the Save method says that an ExternalException will be thrown in one of two situations:
Image was saved with the wrong format.
Image is saved to the file it was created from.
It cannot be that you are saving over the file because you are changing its extension, so it must be the wrong format. What this actually means is not clear. Perhaps one of the source images is using capabilities of the PNG format that cannot be converted to GIF, e.g. alpha channel transparency.
If I may take a moment to make some other suggestions too:
if (Directory.Exists(tempRadarPngToGifDirectory))
{
}
else
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
The empty 'success' case is not required if you invert the logic:
if (!Directory.Exists(tempRadarPngToGifDirectory)
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
Code that manipulates file paths such as the following:
tempRadarPngToGifDirectory = path_exe + "\\" + "tempRadarPngToGifDirectory";
You should consider using the Path class as this will handle the edge cases better and make more portable code:
tempRadarPngToGifDirectory = Path.Combine(path_exe, "tempRadarPngToGifDirectory");