Sign in to follow this  
Headkaze

[.net] Sorting bitmaps by size

Recommended Posts

I have a custom class for sorting bitmaps by their size

class BitmapSizeComparer : IComparer<ImageNode>
{
public int Compare(ImageNode x, ImageNode y)
{
using (Bitmap bmp1 = FileIO.LoadBitmap(x.FileName))
{
using (Bitmap bmp2 = FileIO.LoadBitmap(y.FileName))
{
if (bmp1 != null && bmp2 != null)
return -(bmp1.Width * bmp1.Height).CompareTo(bmp2.Width * bmp2.Height);

}
}

return 0;
}
}


But I want to change it to sort by width and then height rather than width * height. How can I modify it to do that or would I need to sort twice?

Share this post


Link to post
Share on other sites
Try comparing the widths, if the result is non zero return it. Otherwise return the comparison of the heights.

If you are comfortable with linq you can also look into the SortBy and ThenBy methods for a more concise implementation.

Hope this helps

Share this post


Link to post
Share on other sites
Please do realize that the code you posted will be very slow because for each compare action files are read from disc. My guess is that it would be a lot faster if you read all the Sizes first and compare them so you read all the files just once.

Share this post


Link to post
Share on other sites
Quote:
Original post by ernow
Please do realize that the code you posted will be very slow because for each compare action files are read from disc. My guess is that it would be a lot faster if you read all the Sizes first and compare them so you read all the files just once.


I realized that after my post and the Bitmap's sizes are now stored in ImageNode in its constructor.

Thanks turnpast here is the final method..

class BitmapSizeComparer : IComparer<ImageNode>
{
public int Compare(ImageNode x, ImageNode y)
{
int widthCompare = -(x.Size.Width).CompareTo(y.Size.Width);
int heightCompare = -(x.Size.Height).CompareTo(y.Size.Height);

return (widthCompare != 0 ? widthCompare : heightCompare);
}
}




[Edited by - Headkaze on November 10, 2010 3:55:47 PM]

Share this post


Link to post
Share on other sites
what's the context of this code? are the bitmaps already used elsewhere/in memory or do you really need to unload them at the end? is it a memory issue if they are all loaded at once and all removed at once instead of 2 by 2?
If not i'd simply load them all , get rid of the comparer, do an orderby and then dispose of them all?
Images.OrderBy(img=>img.Width * img.Height);

Share this post


Link to post
Share on other sites
It's for an application that packs images into texture sheets (texture atlases). I believe the packing algorithm has better results sorting by width then height rather than width * height.

I did not want to load all the bitmap's into memory at once, so they must be loaded and then sorted, then loaded again to draw onto the texture sheet.

Share this post


Link to post
Share on other sites
An easy optimization is to only load the BMP headers to get size information so that you can perform the sorting, and only load the full bitmap once when it's packed. A quick Google came up with this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this