It’s easy to combine small images to make one giant image, but if there is certain constraint like you have fixed width of the resulting image and you have to make the best use of your space so that things can get in order then there is an opportunity for little brainstorming. Here is a sample code to serve the purpose written in C#. Somebody can use better search and sorting technique according to their need.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
namespace SpriteImage
{
class Program
{
public List<System.Drawing.Bitmap> images = new
List<System.Drawing.Bitmap>();
public int MaxWidth = 90, _index = 0;
public bool[] IsImageSet;
public int[] imageWidth;
Dictionary<int, List<int>> _recordes;
public Dictionary<int, List<int>> Recordes
{
get { return _recordes; }
}
static void Main(string[] args)
{
string[] files = Directory.GetFiles(@"C:\Img\");
Program p = new Program();
System.Drawing.Bitmap combinedImage = p.Combine(files);
combinedImage.Save(@"C:\stitchedImage.Png",
System.Drawing.Imaging.ImageFormat.Png);
}
public void MarkImageAsSet(int index)
{
IsImageSet[index] = true;
}
public Bitmap SearchNextFitImage(int Offset)
{
int[] temp = new int[imageWidth.Length]; int j = 0;
for (int i = 0; i < imageWidth.Length; i++)
{
if (imageWidth[i] <= Offset)
{
if (!IsImageSet[i])
{
temp[j++] = imageWidth[i];
}
}
}
int bigValue = 0;
// find the highest magnitude
for (int i = 0; i < j; i++)
{
bigValue = temp[i] > bigValue ? temp[i] : bigValue;
}
bool IsFound = false;
for (int i = 0; i < imageWidth.Length; i++)
{
if (imageWidth[i] == bigValue)
{
if (!IsImageSet[i])
{
IsFound = true; _index = i;
break;
}
}
}
if (IsFound)
{
return images[_index];
}
else
return null;
}
public Bitmap Combine(string[] files)
{
System.Drawing.Bitmap finalImage = null;
try
{
foreach (string image in files)
{
if (String.Compare("C:\\Img\\Thumbs.db", image) != 0)
{
System.Drawing.Bitmap bitmap = new
System.Drawing.Bitmap(image);
images.Add(bitmap);
}
}
int[] ImageId = new int[images.Count];
for (int i = 0; i < ImageId.Length; i++)
{
ImageId[i] = i;
}
Bitmap temp; int t;
// sort in descending order according to image height.
for (int i = 0; i < images.Count; i++)
{
for (int j = 0; j < images.Count; j++)
{
if (images[i].Height > images[j].Height)
{
temp = images[i];
images[i] = images[j];
images[j] = temp;
t = ImageId[i];
ImageId[i] = ImageId[j];
ImageId[j] = t;
}
}
}
IsImageSet = new bool[images.Count];
imageWidth = new int[images.Count];
// set image width
for (int i = 0; i < images.Count; i++)
{
imageWidth[i] = images[i].Width;
}
//// simulate the possible height
int count = 0, indexTop = 0, offset = 0, width = 0, height =
0;
while (count != images.Count)
{
if (count == 0)
{
// set 1st image
width = images[0].Width;
offset = MaxWidth - width;
MarkImageAsSet(count);
count++; continue;
}
Bitmap nextFitImage = SearchNextFitImage(offset);
if (nextFitImage != null)
{
MarkImageAsSet(_index);
count++;
offset = offset - nextFitImage.Width;
// offsetX = MaxWidth - offset;
Cordinate(offsetX,images[indexTop].Height)
}
else
{
if (!IsImageSet[indexTop + 1])
{
height += images[indexTop].Height;
indexTop++;
offset = MaxWidth - images[indexTop].Width;
count++;
MarkImageAsSet(indexTop);
//Cordinate(0,images[indexTop].Height)
}
// find next available image
else
{
for (int i = 0; i < IsImageSet.Length; i++)
{
if (!IsImageSet[i])
{
height += images[indexTop].Height;
indexTop = i;
offset = MaxWidth - images[i].Width;
count++;
MarkImageAsSet(i);
break;
}
}
}
}
}
height += images[indexTop].Height;
//////////////////
///// now set the images
finalImage = new System.Drawing.Bitmap(MaxWidth, height);
_recordes = new Dictionary<int, List<int>>();
using (System.Drawing.Graphics g =
System.Drawing.Graphics.FromImage(finalImage))
{
g.Clear(System.Drawing.Color.Transparent);
IsImageSet = new bool[images.Count];
count = 0; indexTop = 0; offset = 0; width = 0; height =
0; _index = 0;
int offsetX = 0;
while (count != images.Count)
{
if (count == 0)
{
// set 1st image
width = images[0].Width;
offset = MaxWidth - width;
g.DrawImage(images[0],
new System.Drawing.Rectangle(0, 0,
images[0].Width, images[0].Height));
// set cordinate into dictionary
List<int> point = new List<int>();
point.Add(0); point.Add(0);
_recordes.Add(ImageId[0], point);
//-----------------------
MarkImageAsSet(count);
count++; continue;
}
Bitmap nextFitImage = SearchNextFitImage(offset);
if (nextFitImage != null)
{
MarkImageAsSet(_index);
count++;
offsetX = MaxWidth - offset;
offset = offset - nextFitImage.Width;
if (indexTop == 0)
{
g.DrawImage(images[_index],
new System.Drawing.Rectangle(offsetX, 0,
images[_index].Width, images[_index].Height));
// set cordinate into dictionary
List<int> point = new List<int>();
point.Add(offsetX); point.Add(0);
_recordes.Add(ImageId[_index], point);
//-----------------------
}
else
{
g.DrawImage(images[_index],
new System.Drawing.Rectangle(offsetX,
height, images[_index].Width, images[_index].Height));
// set cordinate into dictionary
List<int> point = new List<int>();
point.Add(offsetX); point.Add(height);
_recordes.Add(ImageId[_index], point);
//-----------------------
}
// Cordinate(offsetX,images[indexTop].Height)
}
else
{
if (!IsImageSet[indexTop + 1])
{
height += images[indexTop].Height;
indexTop++;
offset = MaxWidth - images[indexTop].Width;
g.DrawImage(images[indexTop],
new System.Drawing.Rectangle(0, height,
images[indexTop].Width, images[indexTop].Height));
// set cordinate into dictionary
List<int> point = new List<int>();
point.Add(0); point.Add(height);
_recordes.Add(ImageId[indexTop], point);
//-----------------------
count++;
MarkImageAsSet(indexTop);
//Cordinate(0,images[indexTop].Height)
}
// find next available image
else
{
for (int i = 0; i < IsImageSet.Length; i++)
{
if (!IsImageSet[i])
{
height += images[indexTop].Height;
indexTop = i;
offset = MaxWidth - images[i].Width;
g.DrawImage(images[i],
new System.Drawing.Rectangle(0,
height, images[i].Width, images[i].Height));
// set cordinate into dictionary
List<int> point = new List<int>();
point.Add(0); point.Add(height);
_recordes.Add(ImageId[i], point);
//-----------------------
count++;
MarkImageAsSet(i);
break;
}
}
}
}
}
}
return finalImage;
}
catch (Exception ex)
{
if (finalImage != null)
finalImage.Dispose();
throw ex;
}
finally
{
//clean up memory
foreach (System.Drawing.Bitmap image in images)
{
image.Dispose();
}
}
}
}
}
No comments:
Post a Comment