C# 声明颜色时位图和OutOfMemory异常[8408,8337]
基本上,我的程序是用最简单的嵌套循环逐像素搜索另一幅图像。 它可以在9x9图像中查找2x2,但无法在8408 x 8337分辨率下搜索(我想我不需要那么多,但我想检查它的速度有多慢) 声明彩色2D数组时出错 所以我请求帮助是因为为什么,以及如何解决这个问题 我怀疑OOM错误是由于SizeOfColorType*8337大于Int32。。。但我不确定这是否正确C# 声明颜色时位图和OutOfMemory异常[8408,8337],c#,arrays,memory,bitmap,C#,Arrays,Memory,Bitmap,基本上,我的程序是用最简单的嵌套循环逐像素搜索另一幅图像。 它可以在9x9图像中查找2x2,但无法在8408 x 8337分辨率下搜索(我想我不需要那么多,但我想检查它的速度有多慢) 声明彩色2D数组时出错 所以我请求帮助是因为为什么,以及如何解决这个问题 我怀疑OOM错误是由于SizeOfColorType*8337大于Int32。。。但我不确定这是否正确 using System; using System.Collections.Generic; using System.Linq; us
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace IMGReach
{
class Program
{
static void Main(string[] args)
{
String basePath = @"C:\Users\Administrator\Desktop\IMGReachImages\1.jpg"; // 8408x8337
String searchPath = @"C:\Users\Administrator\Desktop\IMGReachImages\2.jpg"; // 69 x 56
Bitmap b = new Bitmap(basePath); // base image
Bitmap s = new Bitmap(searchPath); // image to search inside of base image
var x = ImageInImage(b, s);
Console.WriteLine(x[0]); // x coord of found image
Console.WriteLine(x[1]); // y coord of found image
Console.Write("END");
Console.ReadKey();
}
private static int[] ImageInImage(Bitmap source, Bitmap searchIt)
{
// Creates array of colors based on image
Color[,] basePixels = AreaToArray(source, 0, 0, source.Width, source.Height);
Color[,] searchPixels = AreaToArray(searchIt, 0, 0, searchIt.Width, searchIt.Height);
Color hookPixel = searchPixels[0, 0];
for (int xpos = 0; xpos < basePixels.GetLength(0); xpos++)
{
for (int ypos = 0; ypos < basePixels.GetLength(1); ypos++)
{
if (basePixels[xpos, ypos] == hookPixel)
{
Color[,] checkMap = AreaToArray(source, xpos, ypos, searchIt.Width, searchIt.Height);
if (sameArray(checkMap, searchPixels))
return new int[] { xpos, ypos };
}
}
}
return null;
}
private static Color[,] AreaToArray(Bitmap source, int start_x, int start_y, int width, int height)
{
if (start_x < 0)
throw new ArgumentException("Invalid parameter value (less than zero)", "start_x");
if (start_y < 0)
throw new ArgumentException("Invalid parameter value (less than zero)", "start_y");
if (width > source.Width)
throw new ArgumentException("Width parameter is bigger than source width", "width");
if (height > source.Height)
throw new ArgumentException("Height parameter is bigger than source height", "height");
Color[,] pixelSet = new Color[width, height]; // [2,2]
for (int ix = 0; ix < width; ix++ )
for (int iy = 0; iy < height; iy++)
pixelSet[ix, iy] = source.GetPixel(ix + start_x, iy + start_y);
return pixelSet;
}
private static bool sameArray(int[,] a1, int[,] a2)
{
if (a1.GetLength(0) != a2.GetLength(0))
return false;
if (a1.GetLength(1) != a2.GetLength(1))
return false;
for (int i = 0; i < a1.GetLength(0); i++)
{
for (int j = 0; j < a1.GetLength(1); j++)
{
if (a1[i, j] == a2[i, j])
{
continue;
}
else
{
return false;
}
}
}
return true;
}
private static bool sameArray(Color[,] a1, Color[,] a2)
{
if (a1.GetLength(0) != a2.GetLength(0))
return false;
if (a1.GetLength(1) != a2.GetLength(1))
return false;
for (int i = 0; i < a1.GetLength(0); i++)
{
for (int j = 0; j < a1.GetLength(1); j++)
{
if (a1[i, j] == a2[i, j])
{
continue;
}
else
{
return false;
}
}
}
return true;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统图;
命名空间IMGReach
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串basePath=@“C:\Users\Administrator\Desktop\IMGReachImages\1.jpg”;//8408x8337
字符串searchPath=@“C:\Users\Administrator\Desktop\IMGReachImages\2.jpg”;//69 x 56
位图b=新位图(基本路径);//基本图像
位图s=新位图(搜索路径);//要在基本图像内部搜索的图像
var x=图像图像(b,s);
Console.WriteLine(x[0]);//找到的映像的x坐标
Console.WriteLine(x[1]);//找到的映像的y坐标
控制台。写入(“结束”);
Console.ReadKey();
}
私有静态int[]ImageInImage(位图源,位图搜索)
{
//基于图像创建颜色数组
颜色[,]基本像素=区域阵列(源,0,0,source.Width,source.Height);
颜色[,]searchPixels=区域阵列(searchIt,0,0,searchIt.Width,searchIt.Height);
颜色hookPixel=searchPixels[0,0];
for(int xpos=0;xpos源宽度)
抛出新ArgumentException(“宽度参数大于源宽度”、“宽度”);
如果(高度>震源高度)
抛出新ArgumentException(“高度参数大于源高度”、“高度”);
颜色[,]像素集=新颜色[宽度,高度];//[2,2]
对于(int-ix=0;ix
8408 x 8337的图像包含7000多万像素。Color
结构的大小至少为4个字节。因此,您尝试分配最小280兆字节。您的系统必须有280 MB的连续可用内存。如果您在32位系统上运行(或在32位模式下运行程序),很可能您没有可用的内存。因此,OutOfMemoryException
情况变得更糟了。即使您设法为该图像分配内存,您的ImageInImage
方法也需要分配大小相同的basePixels
数组
到现在为止,您可能已经注意到,即使在小图像上,您的程序也非常慢。使用
GetPixel
读取图像颜色会非常慢。您需要研究如何使用,以便可以直接访问图像位。该MSDN主题有一个基本示例。如果您想有效地使用内部位图结构,您需要了解一些内部位图结构,但是如果您稍微搜索一下,有很多示例可用。Hmm,但无论如何,我怀疑有一种方法可以做到这一点。。。但是如何管理这么大的内存量呢?@BartłomiejSobieszek将其存储在磁盘中,并对其进行部分查询