Latest Posts

.

Developing an Application, with C# , a bag of chips..and .....a Profiler !(updated)

{ Posted on 11:54 PM by Vivek }
Tags :

My previous post was about a solution to Bloaty Digi-cam photos, since the solution itself was a little tiresome to carry out manually, and there seemed to be no way to automate the process, I decided to do some good in the world, by writing a small application that would do that. Folks I a newbie to software development, and I know how amateurish the whole thing looks, as i write more and more code the more experienced I become,much like a pilot, the more he flies, the more he gains. But not every minute of his flying counts, there will be some tumbling and fumbling in the beginning. The same (I believe) applies to coding, not merely the lines of code,but  the quality of it. You’ll soon see where all this corny talk of mine leads to.

My delusion on the “Apparent success”?
How long did it take to write this app?

Well, an afternoon, by my standards that’s remarkable(actually remarkably deluded), I said to my self, but as my application went to the testing department, everything went down the trenches. The rest of this post is my interesting journey… “Developing an Application, with C# and a bag of chips..and .....Oh a Profiler”

As usual I fired up visual studio, I not a Microsoft shil, but I’ve got to say that in my book there’s no software development without VS.

Then I phrased the problem in my mind, I need to somehow replicate whatever MS Paint is  doing to reduce the size of the images. You’ll find it weird as I did, when you’ve read my previous post. Because effectively what paint was doing we just saving the JPEG to JPEG, no format conversion, re-coding , no rescaling , but it did change its resolution, but only a little.

So in order it achieve that I just have to Load the JPEG image and save it to a file stream again. Seems simple enough.

For those of u from Java background, in .net there are a lot of Nifty classes to play around with Images, using which i can save to and read from many formats Jpg,Bmp,tiff, etc..,The problem was it didn't quite have the effect of MS paint. The file size was still sky-high. So I remembered about the FreeImage library, which i thankfully heard about a year ago. I forgot all the documentation, but it was easy the only problem was it was an unmanaged (ie non- .net ) library, so there is a magic called P/Invoke involved in using a non-managed library, from a managed framework. I know how java programmers feel about this, but dont forget there are a lot of performance incentives involved with a little pain incurred, by writing a wrapper to the non-managed libraries such as FreeImage. Any way I ended up writing a C# wrapper to two important function i needed from the massive 2MB library.

They were

[DllImport("FreeImage.dll")]
public static extern int FreeImage_Load(int format, string filename, int flags);
[DllImport("FreeImage.dll")]
public static extern bool FreeImage_Save(int format, int handle, string filename, int flags);




the parameters are self-explanatory, int format is the file format for Jpeg it was 2,

 



I implemented these things with the following function




public void SaveToJpegOptimized(string UnOptimizedFile,string OptimizedFile)
{
try
{
int a;
a = FreeImage_Load(FIF.FIF_JPEG, UnOptimizedFile, 0);
FreeImage_Save(FIF.FIF_JPEG, a, OptimizedFile, 0);

}
catch(Exception exp)
{
System.Windows.Forms.MessageBox.Show(@"Houston we have a problem " + exp.Message.ToString () );

}
}









Actually there was another function which the application critically needed. More on that later.



Apparently All I had to do was Load the Jpeg and save it.So the logic was sketched. Now coding time…



Some people are religious about whether they should design the UI and code or backwards. I figured out it was better to Design the UI since the application logic was pretty much completed.



so here it is. the  completed UI



image



I could’ve done this a little professionally, but i wanted it to be intuitive and not intimidating for non-geek users. Since were talking about talking to the Hard Disk (pun intended), I decided to go for Asynchronous operation, and It paid off. Especially when the user chooses to operate on multiple files. And with the Minimize to tray option the app sits quietly and does the job on the system tray.



Everything was going great until i decided to put the app to the test.



I mercilessly made it to chew on two hundred files







image



The application before eating the 23rd file, drank  440MB of Precious Memory.



I smelled MEMORY LEAK….



It was time to call the super hero at times of such peril.



TADA the Profiler, a blessing to the developer,



It quickly showed me where I went wrong Of course an experienced developer would a found out the cause in a snap,but it proved difficult for me.



The cause of the application to consume that much memory was that i forgot to call an important function.




[DllImport("FreeImage.dll")]
public static extern void FreeImage_Unload(int handle);






The FreeImage_Unload(int handle) de-allocates the memory needed to hold the image in memory.




private void Folderworkermethod()
{
try
{
string[] files = Directory.GetFiles(textBox2.Text, "*.jpg", SearchOption.TopDirectoryOnly);
DirectoryInfo drin = new DirectoryInfo(textBox2.Text);

FileInfo fileinfo;
progressBar2.Value = 0;
foreach (var file in files)
{
fileinfo = new FileInfo(file);
oldfoldersize += fileinfo.Length;
}
progressBar2.Maximum = files.Length;
drin = null;

oldfoldersize = oldfoldersize / 1024;
lblfoldersize.Text = oldfoldersize.ToString() + "KB";
string tname = "";
this.img = new ImageUtil();
progressBar2.Step = 10;
int filecnt = 0;

foreach (var file in files)
{

filecnt++;
tname = file + ".temp";
if (File.Exists(file + ".temp"))
File.Delete(file + ".temp");


File.Move(file, tname);


img.SaveToJpegOptimized(tname, file);
System.IO.File.Delete(tname);
tname = "";
progressBar2.Value = progressBar2.Value + 1;
lblfilecnt.Text = "File " + filecnt + " of " + files.Length.ToString();

}

foreach (var file in files)
{
fileinfo = new FileInfo(file);
newfoldersize += fileinfo.Length;
}
newfoldersize = newfoldersize / 1024;
lblfolderafter.Text = newfoldersize.ToString() + "KB";
lblfoldersizesav.Text = (oldfoldersize - newfoldersize).ToString();
img = null;
files = null;
}
catch (Exception)
{


}

}







At line number 35 you can see that after a file has been processed the memory can be reused, which the application failed to do.



The code




public void SaveToJpegOptimized(string UnOptimizedFile,string OptimizedFile)
{
try
{
int a;
a = FreeImage_Load(5, UnOptimizedFile, 0);
FreeImage_Save(5, a, OptimizedFile, 0);

}
catch(Exception exp)
{
System.Windows.Forms.MessageBox.Show(@"Houston we have a problem " + exp.Message.ToString () );

}
}





 


Became




public void SaveToJpegOptimized(string UnOptimizedFile,string OptimizedFile)
{
try
{
int a;
a = FreeImage_Load(5,UnOptimizedFile, 0);
FreeImage_Save(5, a, OptimizedFile, 0);
FreeImage_Unload(a);

}
catch(Exception exp)
{
System.Windows.Forms.MessageBox.Show(@"Houston we have a problem " + exp.Message.ToString () );

}
}





That’s right all it took was a single line extra. 8



Folks this is the side effect of managed programming The GC cannot interfere with the unmanaged code region, in C++ as we all know it is left to the coder to dispose all the objects with the( long forgotten )Destructor.(the nostalgic memories may return to haunt you :) . Any way That was it instant cold relief, I mean instant relief from Memory leak.I prescribe a good dose of profiling and experimentation.



Hope the boredom didn't kill you :) .



Until the next adventure



Vivek

A Solution to Bloaty Digi- cam Photos

{ Posted on 6:19 PM by Vivek }

I remember once, when I had to scan 10 or so certificates and photos, and had to E-mail them. As i was uploading them i hit the ceiling of 10 MB quite soon. About the third or fourth picture. I wondered why and as i saw the size they around 2-3 MB . Easily 4 Photos would’ve been enough to reach the 10MB limit. Unfortunately I couldn't “Google” for the lack of time. Then I sort of opened one of pictures with paint (accidentally by clicking “Edit” instead of “Open” in the Explorer context menu). Then I thought I would save the picture to another folder, that would be like copying the same file to another folder.Ok. Not quite. Something interesting happened. The file size was reduced by 70 %. I didn't notice this at first. But I did eventually. Then I repeated it again, with another pic. And ended with a smaller file size.

You dont have to take my word for it

see for yourself

1.98 MB 2592 X 1944

Bloaty Picture

big

523 KB 2592 X 1944


Same picture, Smaller Foot Print

small

That’s roughly 75 % saved without any noticeable difference.

Well if you are a picture lover and have a lot of photos taken with Digi-Cams. You’ll find this, easy on the Hard disks. Ahem.. a little math. Say you have 100 photos with a average file size of 2MB per photo you need .about…? that's right 200MB how much is 75% of 200MB .150MB saved. If you have 1000 photos with 2M average you can save 1.5 GB.Note that I’m being pessimistic, actual results may be greater. On the other hand some times the size may actually increase, a little bit ( 5 – 10 KB).



.

There’s just one catch, you can’t automate (at least as far as i know), paint to do this. So i decided to write a tiny app. That’ll do just that. Actually it doesn't use paint. It uses the infamous FreeImage library.

The following is about the Nitty –Gritty details of the application itself. If you dont like the sound of it just

download the Application here

I just call it the Jpeg Optimizer


Also note: Even though the application does not rescale the image, it does change its resolution but only a little, no noticeable difference unless you choose to zoom 200-500X.
The application does not feature a "backup the images" facility( for now).


Disclaimer:

The software is provided as is, without any warranty. I cannot in any way guarantee the correct functionality of the software. The software is free to use copy an distribute as long as it is intact.

Copyright Notices:

FreeImage Is an open source library maintained by Hervé.Under the GPL license.

Background

The application is built on the .net framework, in C# language. I intentionally decided to target the 2.0 Framework, since many people dont have .net 3.5 installed. Besides I had everything to get going in .net 2.0.The app is multi-threaded for a responsive UI.

More about the application on the next post.