在http://my.oschina.net/sosofy/blog/109259我把图片转化为了字符画,me童鞋建议说是用小图片拼成一个大图片。我觉得这个想法不错,于是动手实现了一下。同样是C#写的,不得不说我自己在平时写的一些代码基本都是C#,python这种很高级的语言,怎么说呢,既然是“玩”,就不太想用C++,太累了 ┐(─_─)┌
下面是关键的代码(PS:还是通过计算像素的亮度,以后尝试用颜色什么的试试!!):
class ImageTools {
// 获取一副图片的平均属性
public static float getAverageProperty(Bitmap bitmap)
{
return getAveragePropertyInArea(bitmap, 0, 0, bitmap.Width, bitmap.Height);
}
/// <summary>
/// 获取指定区域的平均属性
/// </summary>
/// <param name="bitmap">图片</param>
/// <param name="startX">起点的x坐标</param>
/// <param name="startY">起点的y坐标</param>
/// <param name="width">宽度</param>
/// <param name="height">高度</param>
/// <returns></returns>
public static float getAveragePropertyInArea(Bitmap bitmap, int startX, int startY, int width, int height)
{
float averProperty = 0;
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
try
{
Color color = bitmap.GetPixel(startX + w, startY + h);
averProperty += color.GetBrightness();
}
catch (ArgumentOutOfRangeException)
{
averProperty += 0;
}
}
}
return averProperty / (width * height);
}
/// <summary>
/// 创建拼接图片
/// </summary>
/// <param name="target">需要生产的原图的路径</param>
/// <param name="srcRoot">资源的图片文件夹路径</param>
/// <param name="savePath">生产的图片保存路径</param>
/// <param name="xSize"></param>
/// <param name="ySize">和xSize决定原图的多大一块需要被图片替换</param>
/// <param name="scale">缩放比例</param>
public static void createImage(String target, String srcRoot, String savePath, int xSize, int ySize, int scale)
{
Bitmap srcTargetImg = new Bitmap(target);
Bitmap saveImg = new Bitmap(srcTargetImg.Width * scale, srcTargetImg.Height * scale);
Graphics g = Graphics.FromImage(saveImg);
g.Clear(System.Drawing.Color.White);
String[] files = System.IO.Directory.GetFiles(srcRoot);
Hashtable table = new Hashtable();
foreach (String file in files)
{
Bitmap bitmap = new Bitmap(file);
if (bitmap != null)
{
table.Add(file, getAverageProperty(bitmap));
}
}
for (int w = 0; w < srcTargetImg.Width / xSize; w++)
{
for (int h = 0; h < srcTargetImg.Height / ySize; h++)
{
float averProperty = getAveragePropertyInArea(srcTargetImg, w * xSize, h * ySize, xSize, ySize);
// 找到最接近的一张图
String fileToFind = "";
float lastDelta = 2;
foreach (DictionaryEntry de in table)
{
if (Math.Abs(averProperty - (float)de.Value) < lastDelta)
{
lastDelta = Math.Abs(averProperty - (float)de.Value);
fileToFind = (String)de.Key;
}
}
Bitmap tmp = new Bitmap(fileToFind);
// 绘制最终图片
g.DrawImage(tmp, w * xSize * scale, h * ySize * scale, xSize * scale, ySize * scale);
}
}
g.Dispose();
saveImg.Save(savePath);
}
}
最终的效果
原图:
结果(最终图片大小为9600*9600,体积达到夸张的77M):
先来个全貌:
放大一点:
拉近: