0

画像検索/認識用のコードをオンラインで見つけましたが、csharp をほとんど知らないので、それをクラスに入れてビルドしました。vb プロジェクトからアクセスしようとすると、表示されません。参照された後でも、実際にはアクセスできません。関数が共有されていないため、私は推測しています.C#の「静的」はvb.netで「共有」と同じであると理解しています.追加するとエラーが発生します. 't access it?? 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;
    }
}

}

4

2 に答える 2

2

publicクラスにアクセス修飾子を追加していないため、クラスは自動的に として宣言されinternalます。それを修正すると、すべてが機能するはずです。

例:

public class LockedFastImage { /*Your code...*/}
于 2013-01-01T04:25:31.573 に答える
1

クラスでアクセス指定子を指定していないため、デフォルトinternalではクラスがアセンブリの外部にアクセスできない理由です。

クラスと構造体のアクセス修飾子 - MSDN

名前空間内で直接宣言されている (つまり、他のクラスまたは構造体にネストされていない) クラスおよび構造体は、パブリックまたは内部のいずれかになります。アクセス修飾子が指定されていない場合、Internal がデフォルトです。

public class LockedFastImage 
{....

Access Modifier C#が表示される場合があります- MSDN

内部

型またはメンバーは、同じアセンブリ内の任意のコードからアクセスできますが、別のアセンブリからはアクセスできません。

于 2013-01-01T04:28:25.273 に答える