Exemple #1
0
        /// <summary>
        /// スクリーンショットを撮影し、最も近い選択肢画面を返す
        /// </summary>
        /// <returns>
        /// 閾値より距離の小さい選択肢画面が見つかった場合、その <see cref="SelectionInfo"/> と、距離を返します。
        /// 見つからなかった場合、 null と、見つかった中での最短距離を返します。
        /// </returns>
        private async Task <(SelectionInfo, int)> GetMostSimilarSelectionAsync()
        {
            // ハミング距離の閾値
            // 各々の最短距離より十分に小さいので、距離がこれ以下のものがあれば、それを返す
            const int threshold = 10;

            var arrayPool = ArrayPool <byte> .Shared;
            var hashArray = arrayPool.Rent(32);
            var hash      = new ArraySegment <byte>(hashArray, 0, 32);

            var minDistance = int.MaxValue;

            try
            {
                using (var screenshot = await this._wagahighOperator.CaptureContentAsync().ConfigureAwait(false))
                {
                    Blockhash.ComputeHash(new Bgr2432InputImage(screenshot), hash);
                }

                foreach (var si in SelectionInfo.Selections)
                {
                    var distance = Blockhash.GetDistance(hash, si.ScreenshotHash);
                    if (distance <= threshold)
                    {
                        return(si, distance);
                    }
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                    }
                }
            }
            finally
            {
                arrayPool.Return(hashArray);
            }

            return(null, minDistance);
        }
Exemple #2
0
        private int OnExecute()
        {
            var hashLength  = this.Bits * this.Bits / 8;
            var inputLength = this.InputFiles.Length;
            var results     = new byte[hashLength * inputLength];

            // 順番にハッシュを計算
            var successAll = true;

            for (var i = 0; i < this.InputFiles.Length; i++)
            {
                try
                {
                    var span = new Span <byte>(results, hashLength * i, hashLength);

                    using (var image = Image.Load(this.InputFiles[i]))
                    {
                        Blockhash.ComputeHash(new Rgba32InputImage(image), span, this.Bits);
                    }

                    Console.WriteLine("{0}: {1}", i, ToHashString(span));
                }
                catch (Exception ex)
                {
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    Console.Error.WriteLine("{0}: {1}", i, ex);
                    successAll = false;
                }
            }

            if (!successAll)
            {
                return(1);
            }

            // 最短距離を計算
            if (inputLength > 1)
            {
                var minDistance = int.MaxValue;

                for (var i = 0; i < inputLength; i++)
                {
                    for (var j = 0; j < inputLength; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        var bs1      = new ArraySegment <byte>(results, hashLength * i, hashLength);
                        var bs2      = new ArraySegment <byte>(results, hashLength * j, hashLength);
                        var distance = Blockhash.GetDistance(bs1, bs2);

                        if (distance < minDistance)
                        {
                            minDistance = distance;
                        }
                    }
                }

                Console.WriteLine("Min Distance: {0}", minDistance);
            }

            return(0);
        }