Reputation: 702
What I want: image = a square bitmap with Width = Height all images are EXACTLY the same size
I've got a program which draws images on a container. In this case the images are generated bitmaps. The dimensions of the container are generic (the same size as the clientsize of the form).
I want the images laid out in rows and columns. But the drawing part should calculate how many rows and how many columns fit the best for the given amount of images and resize the images to make them fit.
What I've got: code for resizing the object where the images are in
public void ResizeScreen(Size newSize)
{
this.size = newSize;
InitializeObjectSize();
}
code for resizing the images
public void InitializeObjectSize()
{
int objectSize;
int spacing = 10;
if ((this.size.Height - 2 * spacing) <= (this.size.Width - ((objects.Count + 1) * spacing)) / objects.Count)
{
objectSize = this.size.Height - (2 * spacing);
}
else
{
objectSize = (this.size.Width - ((objects.Count + 1) * spacing)) / objects.Count;
}
foreach (Object object in objects)
{
object.Size = objectSize;
}
}
Code for drawing the images/ This one centers the images horizontally and vertically and draws them.
public void DrawObjects()
{
if (objects[0].Image != null)
{
drawImage = new Bitmap(size.Width, size.Height);
System.Drawing.Graphics tempGraphics = Graphics.FromImage(drawImage);
int spacing = 10;
int totalwidth = this.size.Width; //- ((objects.Count * spacing) + spacing);
int totalUsedWidth = objects.Count * objects[0].Size + ((objects.Count * spacing) + spacing);
int realign = (totalwidth - totalUsedWidth) / 2;
for (int i = 0; i < objects.Count; i++)
{
int startxposition = (objects[i].Size * i + 10 * i + 10) + realign;
int startyposition = (size.Height - objects[i].Size) / 2;
tempGraphics.DrawImage(objects[i].ObjectImage, startxposition, startyposition);
}
tempGraphics.Dispose();
}
}
Upvotes: 0
Views: 168
Reputation: 702
This is how I solved it. It's a brute force method.(it will try all combinations and pick the best
public void SetObjectSize()
{
int objectSize = 0;
for (int objectsPerRow = 1; objectsPerRow <= objects.Count ; objectsPerRow++)
{
int rows =(int)Math.Ceiling(((double)objects.Count) / objectsPerRow);
int horizontalSize = (this.size.Height - (rows * spacing + spacing)) / rows;
int verticalSize = (this.size.Width - (objectsPerRow * spacing + spacing)) / objectsPerRow;
int newSize = horizontalSize < verticalSize ? horizontalSize : verticalSize ;
if (newSize > objectSize)
{
this.rows = rows;
this.objectsPerRow = objectsPerRow ;
objectSize = newSize;
}
}
}
Upvotes: 0
Reputation: 9985
First you need the aspect ratio
Double aspectRatio = height/width;
Using the aspect ratio you need a calculation which will turn a number of columns into a number of squares.
Double squares = columns * columns * aspectRatio;
You need the smallest number of squares which is greater than the number of squares you have, so invert the formula.
Double columns = Math.Ceiling(Math.Sqrt(squares / aspectRatio));
Double rows = Math.Ceiling(columns * aspectRatio);
Double actualSquares = rows * columns;
Double squareWidth = width / columns;
Double squareHeight = height / rows;
Note that due to the Math.Ceiling
your squares won't quite be square. You'll need to take the smaller number and calculate the remaining to form a margin, you can then pad each square or form a border
Upvotes: 1