我在网上找到了一些用于图像搜索/识别的代码,因为我几乎不知道任何 csharp,所以我将它放入一个类中并构建它。现在,当我尝试从 vb 项目访问它时,它不显示。即使在引用它之后我也无法实际访问它。我猜测是因为这些函数不是共享的,据我了解,C# 中的“静态”与 vb.net 中的“共享”相同。尽管在添加它时出现错误。任何人都可以确认这是否是问题所在,为什么我可以无法访问它?当我从 vb.net 项目引用该项目时,我也无法访问这些类。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
namespace ImageRecognition
{
class LockedFastImage
{
private Bitmap image;
private byte[] rgbValues;
private System.Drawing.Imaging.BitmapData bmpData;
private IntPtr ptr;
private int bytes;
public LockedFastImage(Bitmap image)
{
this.image = image;
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
bmpData = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, image.PixelFormat);
ptr = bmpData.Scan0;
bytes = Math.Abs(bmpData.Stride) * image.Height;
rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
}
~LockedFastImage()
{
// Try to unlock the bits. Who cares if it dont work...
try
{
image.UnlockBits(bmpData);
}
catch { }
}
/// <summary>
/// Returns or sets a pixel of the image.
/// </summary>
/// <param name="x">x parameter of the pixel</param>
/// <param name="y">y parameter of the pixel</param>
public Color this[int x, int y]
{
get
{
int index = (x + (y * image.Width)) * 4;
return Color.FromArgb(rgbValues[index + 3], rgbValues[index + 2], rgbValues[index + 1], rgbValues[index]);
}
set
{
int index = (x + (y * image.Width)) * 4;
rgbValues[index] = value.B;
rgbValues[index + 1] = value.G;
rgbValues[index + 2] = value.R;
rgbValues[index + 3] = value.A;
}
}
/// <summary>
/// Width of the image.
/// </summary>
public int Width
{
get
{
return image.Width;
}
}
/// <summary>
/// Height of the image.
/// </summary>
public int Height
{
get
{
return image.Height;
}
}
/// <summary>
/// Returns the modified Bitmap.
/// </summary>
public Bitmap asBitmap()
{
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
return image;
}
}
class ImageChecker
{
private LockedFastImage big_image;
private LockedFastImage small_image;
/// <summary>
/// The time needed for last operation.
/// </summary>
public TimeSpan time_needed = new TimeSpan();
/// <summary>
/// Error return value.
/// </summary>
static public Point CHECKFAILED = new Point(-1, -1);
/// <summary>
/// Constructor of the ImageChecker
/// </summary>
/// <param name="big_image">The image containing the small image.</param>
/// <param name="small_image">The image located in the big image.</param>
public ImageChecker(Bitmap big_image, Bitmap small_image)
{
this.big_image = new LockedFastImage(big_image);
this.small_image = new LockedFastImage(small_image);
}
/// <summary>
/// Returns the location of the small image in the big image. Returns CHECKFAILED if not found.
/// </summary>
/// <param name="x_speedUp">speeding up at x achsis.</param>
/// <param name="y_speedUp">speeding up at y achsis.</param>
/// <param name="begin_percent_x">Reduces the search rect. 0 - 100</param>
/// <param name="end_percent_x">Reduces the search rect. 0 - 100</param>
/// <param name="begin_percent_x">Reduces the search rect. 0 - 100</param>
/// <param name="end_percent_y">Reduces the search rect. 0 - 100</param>
public Point bigContainsSmall(int x_speedUp = 1, int y_speedUp = 1, int begin_percent_x = 0, int end_percent_x = 100, int begin_percent_y = 0, int end_percent_y = 100)
{
/*
* SPEEDUP PARAMETER
* It might be enough to check each second or third pixel in the small picture.
* However... In most cases it would be enough to check 4 pixels of the small image for diablo porposes.
* */
/*
* BEGIN, END PARAMETER
* In most cases we know where the image is located, for this we have the begin and end paramenters.
* */
DateTime begin = DateTime.Now;
if (x_speedUp < 1) x_speedUp = 1;
if (y_speedUp < 1) y_speedUp = 1;
if (begin_percent_x < 0 || begin_percent_x > 100) begin_percent_x = 0;
if (begin_percent_y < 0 || begin_percent_y > 100) begin_percent_y = 0;
if (end_percent_x < 0 || end_percent_x > 100) end_percent_x = 100;
if (end_percent_y < 0 || end_percent_y > 100) end_percent_y = 100;
int x_start = (int)((double)big_image.Width * ((double)begin_percent_x / 100.0));
int x_end = (int)((double)big_image.Width * ((double)end_percent_x / 100.0));
int y_start = (int)((double)big_image.Height * ((double)begin_percent_y / 100.0));
int y_end = (int)((double)big_image.Height * ((double)end_percent_y / 100.0));
/*
* We cant speed up the big picture, because then we have to check pixels in the small picture equal to the speeded up size
* for each pixel in the big picture.
* Would give no speed improvement.
* */
//+ 1 because first pixel is in picture. - small because image have to be fully in the other image
for (int x = x_start; x < x_end - small_image.Width + 1; x++)
for (int y = y_start; y < y_end - small_image.Height + 1; y++)
{
//now we check if all pixels matches
for (int sx = 0; sx < small_image.Width; sx += x_speedUp)
for (int sy = 0; sy < small_image.Height; sy += y_speedUp)
{
if (small_image[sx, sy] != big_image[x + sx, y + sy])
goto CheckFailed;
}
//check ok
time_needed = DateTime.Now - begin;
return new Point(x, y);
CheckFailed: ;
}
time_needed = DateTime.Now - begin;
return CHECKFAILED;
}
}
}
您没有将
public
访问修饰符添加到您的类中,因此类会自动声明为 internal
。修复它,一切都应该正常。
示例:
public class LockedFastImage { /*Your code...*/}
您没有为您的类指定任何访问说明符,因此默认情况下您的类是
internal
,这就是为什么您无法在程序集外部访问它。
直接在命名空间中声明的类和结构(在 换句话说,没有嵌套在其他类或结构中)可以 可以是公共的,也可以是内部的。 如果没有访问权限,则默认为内部 修饰符已指定。
public class LockedFastImage
{....
您可能会看到访问修饰符 C# - MSDN
内部
同一程序集中的任何代码都可以访问类型或成员, 但不是来自另一个程序集。