The code is working.
But, now I'm showing for each file the download progress in progressBar1.
But I want to add to the designer( added already ) progressBar2 to show the overall download progress. How can I calculate it and display it in progressBar2 ?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
using System.Diagnostics;
namespace DownloadFiles
{
public partial class Form1 : Form
{
Stopwatch sw = new Stopwatch();
int count = 0;
PictureBoxBigSize pbbs;
ExtractImages ei = new ExtractImages();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btnDownload_Click(object sender, EventArgs e)
{
downloadFile(filesUrls);
}
private Queue<string> _downloadUrls = new Queue<string>();
private async void downloadFile(IEnumerable<string> urls)
{
foreach (var url in urls)
{
_downloadUrls.Enqueue(url);
}
await DownloadFile();
}
private async Task DownloadFile()
{
if (_downloadUrls.Any())
{
WebClient client = new WebClient();
client.DownloadProgressChanged += ProgressChanged;
client.DownloadFileCompleted += Completed;
var url = _downloadUrls.Dequeue();
await client.DownloadFileTaskAsync(new Uri(url), #"C:\Temp\DownloadFiles\" + count + ".jpg");
return;
}
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// Calculate download speed and output it to labelSpeed.
Label2.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
// Update the progressbar percentage only when the value is not the same.
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());//e.ProgressPercentage;
// Show the percentage on our label.
Label4.Text = e.ProgressPercentage.ToString() + "%";
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
Label5.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
}
// The event that will trigger when the WebClient is completed
private async void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled == true)
{
MessageBox.Show("Download has been canceled.");
}
else
{
ProgressBar1.Value = 100;
count++;
await DownloadFile();
}
}
}
}
Try adding this method which calculates the total amount of bytes needing to be downloaded (or modify an existing method, whatever you decide):
long totalBytesToDownload = 0;
List<FileInfo> files;
private void getTotalBytes(IEnumerable<string> urls)
{
files = new List<FileInfo>(urls.Count());
foreach(string url in urls)
{
files.Add(new FileInfo(url));
}
files.ForEach(file => totalBytesToDownload += file.Length);
}
So what i've done here is added a method that gets the total amount of bytes to be downloaded, and also created a variable that stores the file size for each file your trying to download, which will be used here in a minute.
First, in your Complete event, we need to create a variable that stores the number of bytes after each file download, which we will use later.
long bytesFromCompletedFiles = 0;
private async void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled == true)
{
MessageBox.Show("Download has been canceled.");
}
else
{
ProgressBar1.Value = 100;
count++;
bytesFromCompletedFiles += files[count - 1].Length;
await DownloadFile();
}
}
And finally, we can update the ProgressChanged event to finish your ProgressBar2:
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// Calculate download speed and output it to labelSpeed.
Label2.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
// Update the progressbar percentage only when the value is not the same.
double bytesInCurrentDownload = double.Parse(e.BytesReceived.ToString());
double totalBytesCurrentDownload = double.Parse(e.TotalBytesToReceive.ToString());
double percentageCurrentDownload = bytesInCurrentDownload / totalBytesCurrentDownload * 100;
ProgressBar1.Value = int.Parse(Math.Truncate(percentageCurrentDownload).ToString());//e.ProgressPercentage;
// Show the percentage on our label.
Label4.Text = e.ProgressPercentage.ToString() + "%";
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
Label5.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
//Let's update ProgressBar2
double totalBytesDownloaded = e.BytesReceived + bytesFromCompletedFiles;
double percentageTotalDownload = totalBytesDownloaded / totalBytesToDownload * 100;
ProgressBar2.Value = int.Parse(Math.Truncate(percentageTotalDownload)).ToString();
}
Hopefully, this works for you!
Related
In the screenshot the Download Speed = show the infinity sign kb/s instead the speed.
The speed label show infinity sign from the second downloading file and so on
The first downloading file it's showing fine the speed but then from the second it's showing the infinity sign. How can I fix it so it will show the speed for each file ?
The downloading method :
private async Task DownloadAsync()
{
using (var client = new WebClient())
{
client.DownloadFileCompleted += (s, e) => lblStatus.Text = "Download File Completed.";
client.DownloadFileCompleted += (s, e) => sw.Reset();
client.DownloadProgressChanged += (s, e) => progressBar1.Value = e.ProgressPercentage;
client.DownloadProgressChanged += (s, e) => lblAmount.Text = FormatBytes(e.BytesReceived);
client.DownloadProgressChanged += (s, e) => lblSpeed.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
client.DownloadProgressChanged += (s, e) => lblDownloadSize.Text = Convert.ToInt64(client.ResponseHeaders["Content-Length"]).ToString();
client.DownloadProgressChanged += (s, e) =>
{
lblDownloadProgress.Text = "%" + e.ProgressPercentage.ToString();
lblDownloadProgress.Left = Math.Min(
(int)(progressBar1.Left + e.ProgressPercentage / 100f * progressBar1.Width),
progressBar1.Width - lblDownloadProgress.Width
);
};
for (int i = 0; i < urls.Count; i++)
{
await client.DownloadFileTaskAsync(new Uri(urls[i]), #"d:\satImages\img" + i + ".gif");
}
}
}
Format bytes method :
private string FormatBytes(long bytes)
{
string[] Suffix = { "B", "KB", "MB", "GB", "TB" };
int i;
double dblSByte = bytes;
for (i = 0; i < Suffix.Length && bytes >= 1024; i++, bytes /= 1024)
{
dblSByte = bytes / 1024.0;
}
return String.Format("{0:0.00} {1}", dblSByte, Suffix[i]);
}
And in a button click event starting it :
private async void btnStart_Click(object sender, EventArgs e)
{
lblStatus.Text = "Downloading...";
sw.Start();
await DownloadAsync();
}
Before i tried to check if progressBar2 that show overall download progress is at 100% but it's not really working. Is there another way more sure way to check it ?
private void btnDownload_Click(object sender, EventArgs e)
{
//urll.Add("http://download.thinkbroadband.com/1GB.zip");
btnDownload.Enabled = false;
label7.Text = "Downloading...";
getTotalBytes(countryList);
CreateCountryDateTimeDirectories(newList);
downloadFile(newList);
}
private Queue<string> _downloadUrls = new Queue<string>();
private async void downloadFile(IEnumerable<string> urls)
{
foreach (var url in urls)
{
_downloadUrls.Enqueue(url);
}
await DownloadFile();
}
private async Task DownloadFile()
{
if (_downloadUrls.Any())
{
WebClient client = new WebClient();
client.DownloadProgressChanged += ProgressChanged;
client.DownloadFileCompleted += Completed;
var url = _downloadUrls.Dequeue();
sw = Stopwatch.StartNew();
if (url.Contains("true"))
{
await client.DownloadFileTaskAsync(new Uri(url), countriesMainPath + "\\" + currentDownloadCountry + "\\" + count + "Infrared.jpg");
}
else
{
await client.DownloadFileTaskAsync(new Uri(url), countriesMainPath + "\\" + currentDownloadCountry + "\\" + count + "Invisible.jpg");
}
return;
}
}
double percentageTotalDownload = 0;
double totalBytesDownloaded = 0;
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// Calculate download speed and output it to labelSpeed.
label3.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
// Update the progressbar percentage only when the value is not the same.
double bytesInCurrentDownload = (double)e.BytesReceived;
double totalBytesCurrentDownload = double.Parse(e.TotalBytesToReceive.ToString());
double percentageCurrentDownload = bytesInCurrentDownload / totalBytesCurrentDownload * 100;
ProgressBar1.Value = int.Parse(Math.Truncate(percentageCurrentDownload).ToString());//e.ProgressPercentage;
// Show the percentage on our label.
Label4.Text = e.ProgressPercentage.ToString() + "%";
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
label10.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
//Let's update ProgressBar2
totalBytesDownloaded = e.BytesReceived + bytesFromCompletedFiles;
percentageTotalDownload = totalBytesDownloaded / totalBytesToDownload * 100;
progressBar2.Value = (int)percentageTotalDownload;
label6.Text = progressBar2.Value.ToString() + "%";
}
long bytesFromCompletedFiles = 0;
// The event that will trigger when the WebClient is completed
private async void Completed(object sender, AsyncCompletedEventArgs e)
{
await DownloadFile();
}
For example if i have 100 urls and it's start downloading then i want to know in the completed event when all the files downloaded and not only one each time.
You can keep track of how many downloads have been completed in an counter variable. Because of the multiple threads that can access that counter, use the Interlocked class to manipulate that counter.
This are the changes needed in your code:
private int urlCount = 0; // keep track of how many urls are processed
private async void downloadFile(IEnumerable<string> urls)
{
urlCount = 0;
foreach (var url in urls)
{
_downloadUrls.Enqueue(url);
urlCount++;
}
// urlCount is now set
await DownloadFile();
}
And here is the handling of the counter and the check if we are done
private async void Completed(object sender, AsyncCompletedEventArgs e)
{
// urlCount will be decremented
// cnt will get its value
var cnt = System.Threading.Interlocked.Decrement(ref urlCount);
if (cnt > 0) {
await DownloadFile();
}
else
{
// call here what ever you want to happen when everything is
// downloaded
"Done".Dump();
}
}
I haven't understood it very well, but what you are trying to accomplish is that your progress bar is showing progress of download all files and not one file then reset then another file that reset.
If that is the case, then why you do not try foreach file get size and sum it to totalBytesToDownload and then use it in progress bar
So
foreach(string url in urll)
{
//get url file size
totalBytesToDownload = totalBytesToDownload + urlSizeYouGot;
}
Here is some code that I use to download a file and then calculate the time remaining time and kbps. It will then post those results on the form by updating a text box and it has a progress bar. The problem I am having is the UI is freezing and I am thinking it might be how I am using the stopwatch but not sure. Anyone have any input?
/// Downloads the file.
private void Download_Begin()
{
web_client = new System.Net.WebClient();
web_client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Download_Progress);
web_client.DownloadFileCompleted += new AsyncCompletedEventHandler(Download_Complete);
stop_watch = new System.Diagnostics.Stopwatch();
stop_watch.Start();
try
{
if (Program.Current_Download == "Install_Client.exe")
{
web_client.DownloadFileAsync(new Uri("http://www.website.com/Client/Install_Client.exe"), #"C:\Downloads\Install_Client.exe");
}
else
{
web_client.DownloadFileAsync(new Uri((string.Format("http://www.website.com/{0}", Program.Current_Download))), (string.Format(#"C:\Downloads\{0}", Program.Current_Download)));
}
}
catch(Exception)
{
stop_watch.Stop();
}
Program.Downloading = true;
Download_Success = false;
}
/// -------------------
/// Tracks download progress.
private void Download_Progress(object sender, DownloadProgressChangedEventArgs e)
{
double bs = e.BytesReceived / stop_watch.Elapsed.TotalSeconds;
this.label_rate.Text = string.Format("{0} kb/s", (bs / 1024d).ToString("0.00"));
long bytes_remaining = e.TotalBytesToReceive - e.BytesReceived;
double time_remaining_in_seconds = bytes_remaining / bs;
var remaining_time = TimeSpan.FromSeconds(time_remaining_in_seconds);
string hours = remaining_time.Hours.ToString("00");
if (remaining_time.Hours > 99)
{
hours = remaining_time.Hours.ToString("000");
}
this.time_remaining.Text = string.Format("{0}::{1}::{2} Remaining", hours, remaining_time.Minutes.ToString("00"), remaining_time.Seconds.ToString("00"));
progressBar1.Maximum = (int)e.TotalBytesToReceive / 100;
progressBar1.Value = (int)e.BytesReceived / 100;
if (e.ProgressPercentage == 100)
{
Download_Success = true;
}
}
/// -------------------------
The UI thread could be freezing for various reasons, despite the fact that you are calling the asynchronous download function. One way of preventing the UI to freeze would be to invoke the downloading of the file from different thread than the UI. For instance you can accomplish this with BackgroundWorker and safely modify form's controls via thread safe calls or in short wrapping the code executed in the non-UI thread with BeginInvoke() calls.
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += Worker_DoWork;
worker.RunWorkerAsync();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Download_Begin();
}
/// Downloads the file.
private void Download_Begin()
{
web_client = new System.Net.WebClient();
web_client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Download_Progress);
web_client.DownloadFileCompleted += new AsyncCompletedEventHandler(Download_Complete);
stop_watch = new System.Diagnostics.Stopwatch();
stop_watch.Start();
try
{
if (Program.Current_Download == "Install_Client.exe")
{
web_client.DownloadFileAsync(new Uri("http://www.website.com/Client/Install_Client.exe"), #"C:\Downloads\Install_Client.exe");
}
else
{
web_client.DownloadFileAsync(new Uri((string.Format("http://www.website.com/{0}", Program.Current_Download))), (string.Format(#"C:\Downloads\{0}", Program.Current_Download)));
}
}
catch (Exception)
{
stop_watch.Stop();
}
Program.Downloading = true;
Download_Success = false;
}
/// -------------------
/// Tracks download progress.
private void Download_Progress(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke(new Action(() =>
{
double bs = e.BytesReceived / stop_watch.Elapsed.TotalSeconds;
this.label_rate.Text = string.Format("{0} kb/s", (bs / 1024d).ToString("0.00"));
long bytes_remaining = e.TotalBytesToReceive - e.BytesReceived;
double time_remaining_in_seconds = bytes_remaining / bs;
var remaining_time = TimeSpan.FromSeconds(time_remaining_in_seconds);
string hours = remaining_time.Hours.ToString("00");
if (remaining_time.Hours > 99)
{
hours = remaining_time.Hours.ToString("000");
}
this.time_remaining.Text = string.Format("{0}::{1}::{2} Remaining", hours, remaining_time.Minutes.ToString("00"), remaining_time.Seconds.ToString("00"));
progressBar1.Maximum = (int)e.TotalBytesToReceive / 100;
progressBar1.Value = (int)e.BytesReceived / 100;
if (e.ProgressPercentage == 100)
{
Download_Success = true;
}
}));
}
Some thoughts about your code:
No need to close stopwatch when exceptions happen, stopwatch does not do any work inside, it simply remember current time when you start stopwatch and calculate difference when you access elapsed time.
When you catch all exceptions, there is no need to provide Exception class (i.e. catch instead of catch(Exception)).
Mark download as completed only in DownloadFileCompleted event, not in DownloadProgressChanged, because ProgressPercentage can be 100 even when download is not completed yet.
When working with async code it is always better to initialize status variables (in your case Download_Success and Program.Downloading) before calling async method, not after.
Now about freezes. DownloadProgreesChanged can be fired very often by WebClient, so UI thread can be flooded by update messages. You need to split report progress and update UI code. UI should be updated in timed manner, for example, twice per second. Very rough code sample below:
// Put timer on your form, equivalent to:
// Update_Timer = new System.Windows.Forms.Timer();
// Update_Timer.Interval = 500;
// Update_Timer.Tick += Timer_Tick;
private void Download_Begin()
{
web_client = new System.Net.WebClient();
web_client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Download_Progress);
web_client.DownloadFileCompleted += new AsyncCompletedEventHandler(Download_Complete);
Program.Downloading = true;
Download_Success = false;
stop_watch = System.Diagnostics.Stopwatch.StartNew();
Update_Timer.Start();
web_client.DownloadFileAsync(new Uri("uri"), "path");
}
private int _Progress;
private void Download_Progress(object sender, DownloadProgressChangedEventArgs e)
{
_Progress = e.ProgressPercentage;
}
private void Download_Complete(object sender, AsyncCompletedEventArgs e)
{
Update_Timer.Stop();
Program.Downloading = false;
Download_Success = true;
}
private void Timer_Tick(object sender, EventArgs e)
{
// Your code to update remaining time and speed
// this.label_rate.Text = ...
// this.time_remaining.Text = ...
progressBar1.Value = _Progress;
}
I would like to perform the following action in C#:
Read the amount of lines in a specific text file.
Depending on the amount of lines in a text file, read each line and update the progress bar.
This is what I have so far:
private void Form1_Load(object sender, System.EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
int lineCount = 0;
int max = 100;
float percent;
using (var reader = File.OpenText(#"C:\file.txt"))
{
toolStripLabel1.Text = "Initializing...";
while (reader.ReadLine() != null)
{
lineCount++;
}
reader.Close();
for (int i = 0; i < lineCount; i++)
{
percent = (max / lineCount);
toolStripLabel1.Text = i.ToString() + " - " + percent + "%";
bw.ReportProgress(Convert.ToInt32(percent));
percent = percent + percent;
// Thread.Sleep(100);
}
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
// progressBar1.Value = (int)(((decimal)currentPosition / (decimal)length) * (decimal)100);
this.Text = e.ProgressPercentage.ToString();
}
Anyone have an idea on how to properly calculate and display the progress bar depending on what line is being read from the file?
Thanks in advance!
There are several problems with your code:
You're first reading the file, then after it has all been read you start updating the progress bar, which doesn't really make any sense.
You're doing integer division in your percentage calculation.
The percentage calculation isn't quite right.
You're updating the ToolStripLabel from the worker thread.
Try this:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
var files = File.ReadAllLines( #"C:\file.txt" );
for( int i = 0; i < files.Length; i++ )
{
var line = files[i];
// do work on the current line here
int percentage = (int)( ( i / (double)files.Length ) * 100.0 );
bw.ReportProgress( percentage );
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
toolStripLabel1.Text = e.ProgressPercentage.ToString() + "%";
this.Text = e.ProgressPercentage.ToString();
}
If the file is very large and it's the actual reading that takes time, you should go back to your original way of reading it, but update the progress for every line instead of after. Though then you're back to the issue of not knowing how many lines there are before you have read the file. In that case - you could estimate the progress based on how many bytes/chars you have read compared to the full size of the file, which you can get without reading it all.
There are a few things you need to do
try this : replace
percent = (max / lineCount);
with this
percent = (100.0 * i / lineCount);
and remove percent = percent + percent;
Try this:
private void InvokeLabel(string text)
{
if (toolStripLabel1.InvokeRequired)
{
toolStripLabel1.Invoke(new Action<string>(InvokeLabel), text);
}
else
{
toolStripLabel1.Text = text;
}
}
For your progress bar it's the same code
I'm trying to show a form that displays a label like "Updating, this window will close once update has finished" to download a few images files. I put this on my form's shown.
private void frmExtraUpdater_Shown(object sender, EventArgs e)
{
for (int i = 1; i < 8; i++)
{
string _EmoticonURL = String.Format("https://dl.dropboxusercontent.com/u/110636189/MapleEmoticons/f{0}.bmp", i);
WebRequest requestPic = WebRequest.Create(_EmoticonURL);
WebResponse responsePic = requestPic.GetResponse();
Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error
webImage.Save(Application.StartupPath + #"\Images\f" + i + ".bmp");
}
}
However.. once the form is shown, the label doesn't even show because it doesn't load it (It insantly downloades the images. I want it to show the label and only then start the download).
The other problem is that it throws "A generic error occurred in GDI+." on the webImgae.Save part for some reason.
Why's that?
Oh and.. if the folder "Images" does not exist, will it automatically create it?
Thanks!
Here is Jon Skeet suggestion:
System.Net.WebClient webClient = new System.Net.WebClient();
webClient.DownloadFile(String.Format("https://dl.dropboxusercontent.com/u/110636189/MapleEmoticons/f{0}.bmp", i), Application.StartupPath + #"\Images\f" + i + ".bmp");
Use a background worker to update any UI components
BackgroundWorker backTask = new BackgroundWorker();
public frmExtraUpdater()
{
backTask.DoWork += backTask_DoWork;
backTask.RunWorkerCompleted += backTask_RunWorkerCompleted;
}
private void frmExtraUpdater_Shown(object sender, EventArgs e)
{
yourLabel.Text = "Downloading";
backTask.RunWorkerAsync();
}
void backTask_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i < 8; i++)
{
System.Net.WebClient webClient = new System.Net.WebClient();
webClient.DownloadFile(String.Format("https://dl.dropboxusercontent.com/u/110636189/MapleEmoticons/f{0}.bmp", i), Application.StartupPath + #"\Images\f" + i + ".bmp");
backTask.ReportProgress(i * (100 / 8), String.Format("https://dl.dropboxusercontent.com/u/110636189/MapleEmoticons/f{0}.bmp", i));
}
}
void backTask_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
yourLabel.Text = "Downloading" + e.UserState.ToString();
}
void backTask_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
You should use an async method, with webrequest async api (if you work with .net 4.5 or sup) or download your images in a background thread to avoid ui thread blocking.
You can try that:
private void frmExtraUpdater_Shown(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, d) =>
{
saveImages();
};
worker.RunWorkerCompleted += (o, f) =>
{
this.Close();
};
worker.RunWorkerAsync();
}
private void saveImages()
{
for (int i = 1; i < 8; i++)
{
string _EmoticonURL = String.Format("https://dl.dropboxusercontent.com/u/110636189/MapleEmoticons/f{0}.bmp", i);
WebRequest requestPic = WebRequest.Create(_EmoticonURL);
WebResponse responsePic = requestPic.GetResponse();
Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error
webImage.Save(Application.StartupPath + #"\Images\f" + i + ".bmp");
}
}